@treeui/vue 0.8.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/components/TAccordion.cjs +2 -0
- package/dist/components/TAccordion.cjs.map +1 -0
- package/dist/components/TAccordion.js +7 -0
- package/dist/components/TAccordion.js.map +1 -0
- package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.js +97 -0
- package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TAccordionItem.cjs +2 -0
- package/dist/components/TAccordionItem.cjs.map +1 -0
- package/dist/components/TAccordionItem.js +7 -0
- package/dist/components/TAccordionItem.js.map +1 -0
- package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.js +83 -0
- package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TAlert.cjs +2 -0
- package/dist/components/TAlert.cjs.map +1 -0
- package/dist/components/TAlert.js +7 -0
- package/dist/components/TAlert.js.map +1 -0
- package/dist/components/TAlert.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TAlert.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TAlert.vue_vue_type_script_setup_true_lang.js +57 -0
- package/dist/components/TAlert.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TAvatar.cjs +2 -0
- package/dist/components/TAvatar.cjs.map +1 -0
- package/dist/components/TAvatar.js +7 -0
- package/dist/components/TAvatar.js.map +1 -0
- package/dist/components/TAvatar.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TAvatar.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TAvatar.vue_vue_type_script_setup_true_lang.js +46 -0
- package/dist/components/TAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TBadge.cjs +2 -0
- package/dist/components/TBadge.cjs.map +1 -0
- package/dist/components/TBadge.js +7 -0
- package/dist/components/TBadge.js.map +1 -0
- package/dist/components/TBadge.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TBadge.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TBadge.vue_vue_type_script_setup_true_lang.js +27 -0
- package/dist/components/TBadge.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TBreadcrumb.cjs +2 -0
- package/dist/components/TBreadcrumb.cjs.map +1 -0
- package/dist/components/TBreadcrumb.js +7 -0
- package/dist/components/TBreadcrumb.js.map +1 -0
- package/dist/components/TBreadcrumb.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TBreadcrumb.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TBreadcrumb.vue_vue_type_script_setup_true_lang.js +20 -0
- package/dist/components/TBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TBreadcrumbItem.cjs +2 -0
- package/dist/components/TBreadcrumbItem.cjs.map +1 -0
- package/dist/components/TBreadcrumbItem.js +7 -0
- package/dist/components/TBreadcrumbItem.js.map +1 -0
- package/dist/components/TBreadcrumbItem.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TBreadcrumbItem.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TBreadcrumbItem.vue_vue_type_script_setup_true_lang.js +28 -0
- package/dist/components/TBreadcrumbItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TButton.cjs +2 -0
- package/dist/components/TButton.cjs.map +1 -0
- package/dist/components/TButton.js +7 -0
- package/dist/components/TButton.js.map +1 -0
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js +91 -0
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TCard.cjs +2 -0
- package/dist/components/TCard.cjs.map +1 -0
- package/dist/components/TCard.js +7 -0
- package/dist/components/TCard.js.map +1 -0
- package/dist/components/TCard.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TCard.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TCard.vue_vue_type_script_setup_true_lang.js +42 -0
- package/dist/components/TCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TCheckbox.cjs +2 -0
- package/dist/components/TCheckbox.cjs.map +1 -0
- package/dist/components/TCheckbox.js +7 -0
- package/dist/components/TCheckbox.js.map +1 -0
- package/dist/components/TCheckbox.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TCheckbox.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TCheckbox.vue_vue_type_script_setup_true_lang.js +106 -0
- package/dist/components/TCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TCombobox.cjs +2 -0
- package/dist/components/TCombobox.cjs.map +1 -0
- package/dist/components/TCombobox.js +7 -0
- package/dist/components/TCombobox.js.map +1 -0
- package/dist/components/TCombobox.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TCombobox.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TCombobox.vue_vue_type_script_setup_true_lang.js +282 -0
- package/dist/components/TCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TConfirmDialog.cjs +2 -0
- package/dist/components/TConfirmDialog.cjs.map +1 -0
- package/dist/components/TConfirmDialog.js +7 -0
- package/dist/components/TConfirmDialog.js.map +1 -0
- package/dist/components/TConfirmDialog.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TConfirmDialog.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TConfirmDialog.vue_vue_type_script_setup_true_lang.js +145 -0
- package/dist/components/TConfirmDialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TContainer.cjs +2 -0
- package/dist/components/TContainer.cjs.map +1 -0
- package/dist/components/TContainer.js +7 -0
- package/dist/components/TContainer.js.map +1 -0
- package/dist/components/TContainer.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TContainer.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TContainer.vue_vue_type_script_setup_true_lang.js +43 -0
- package/dist/components/TContainer.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TContextMenu.cjs +2 -0
- package/dist/components/TContextMenu.cjs.map +1 -0
- package/dist/components/TContextMenu.js +7 -0
- package/dist/components/TContextMenu.js.map +1 -0
- package/dist/components/TContextMenu.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TContextMenu.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TContextMenu.vue_vue_type_script_setup_true_lang.js +149 -0
- package/dist/components/TContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TDatePicker.cjs +2 -0
- package/dist/components/TDatePicker.cjs.map +1 -0
- package/dist/components/TDatePicker.js +7 -0
- package/dist/components/TDatePicker.js.map +1 -0
- package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.js +305 -0
- package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TDateTimePicker.cjs +2 -0
- package/dist/components/TDateTimePicker.cjs.map +1 -0
- package/dist/components/TDateTimePicker.js +7 -0
- package/dist/components/TDateTimePicker.js.map +1 -0
- package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.js +409 -0
- package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TDivider.cjs +2 -0
- package/dist/components/TDivider.cjs.map +1 -0
- package/dist/components/TDivider.js +7 -0
- package/dist/components/TDivider.js.map +1 -0
- package/dist/components/TDivider.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TDivider.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TDivider.vue_vue_type_script_setup_true_lang.js +30 -0
- package/dist/components/TDivider.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TDrawer.cjs +2 -0
- package/dist/components/TDrawer.cjs.map +1 -0
- package/dist/components/TDrawer.js +7 -0
- package/dist/components/TDrawer.js.map +1 -0
- package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.js +168 -0
- package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TDropdown.cjs +2 -0
- package/dist/components/TDropdown.cjs.map +1 -0
- package/dist/components/TDropdown.js +7 -0
- package/dist/components/TDropdown.js.map +1 -0
- package/dist/components/TDropdown.vue.d.ts +3 -0
- package/dist/components/TDropdown.vue.d.ts.map +1 -1
- package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.js +176 -0
- package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TEmptyState.cjs +2 -0
- package/dist/components/TEmptyState.cjs.map +1 -0
- package/dist/components/TEmptyState.js +7 -0
- package/dist/components/TEmptyState.js.map +1 -0
- package/dist/components/TEmptyState.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TEmptyState.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TEmptyState.vue_vue_type_script_setup_true_lang.js +64 -0
- package/dist/components/TEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TFileUpload.cjs +2 -0
- package/dist/components/TFileUpload.cjs.map +1 -0
- package/dist/components/TFileUpload.js +7 -0
- package/dist/components/TFileUpload.js.map +1 -0
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.js +284 -0
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TFormField.cjs +2 -0
- package/dist/components/TFormField.cjs.map +1 -0
- package/dist/components/TFormField.js +7 -0
- package/dist/components/TFormField.js.map +1 -0
- package/dist/components/TFormField.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TFormField.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TFormField.vue_vue_type_script_setup_true_lang.js +63 -0
- package/dist/components/TFormField.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TGrid.cjs +2 -0
- package/dist/components/TGrid.cjs.map +1 -0
- package/dist/components/TGrid.js +7 -0
- package/dist/components/TGrid.js.map +1 -0
- package/dist/components/TGrid.vue.d.ts +1 -1
- package/dist/components/TGrid.vue.d.ts.map +1 -1
- package/dist/components/TGrid.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TGrid.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TGrid.vue_vue_type_script_setup_true_lang.js +47 -0
- package/dist/components/TGrid.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TIcon.cjs +2 -0
- package/dist/components/TIcon.cjs.map +1 -0
- package/dist/components/TIcon.js +7 -0
- package/dist/components/TIcon.js.map +1 -0
- package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.js +39 -0
- package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TInput.cjs +2 -0
- package/dist/components/TInput.cjs.map +1 -0
- package/dist/components/TInput.js +7 -0
- package/dist/components/TInput.js.map +1 -0
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.js +80 -0
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TLink.cjs +2 -0
- package/dist/components/TLink.cjs.map +1 -0
- package/dist/components/TLink.js +7 -0
- package/dist/components/TLink.js.map +1 -0
- package/dist/components/TLink.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TLink.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TLink.vue_vue_type_script_setup_true_lang.js +47 -0
- package/dist/components/TLink.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TMarkdownEditor.cjs +2 -0
- package/dist/components/TMarkdownEditor.cjs.map +1 -0
- package/dist/components/TMarkdownEditor.js +7 -0
- package/dist/components/TMarkdownEditor.js.map +1 -0
- package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.cjs +12 -0
- package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.js +315 -0
- package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TModal.cjs +2 -0
- package/dist/components/TModal.cjs.map +1 -0
- package/dist/components/TModal.js +7 -0
- package/dist/components/TModal.js.map +1 -0
- package/dist/components/TModal.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TModal.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TModal.vue_vue_type_script_setup_true_lang.js +163 -0
- package/dist/components/TModal.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TMultiSelect.cjs +2 -0
- package/dist/components/TMultiSelect.cjs.map +1 -0
- package/dist/components/TMultiSelect.js +7 -0
- package/dist/components/TMultiSelect.js.map +1 -0
- package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.js +282 -0
- package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TNavMenu.cjs +2 -0
- package/dist/components/TNavMenu.cjs.map +1 -0
- package/dist/components/TNavMenu.js +7 -0
- package/dist/components/TNavMenu.js.map +1 -0
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js +151 -0
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TNavbar.cjs +2 -0
- package/dist/components/TNavbar.cjs.map +1 -0
- package/dist/components/TNavbar.js +7 -0
- package/dist/components/TNavbar.js.map +1 -0
- package/dist/components/TNavbar.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TNavbar.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TNavbar.vue_vue_type_script_setup_true_lang.js +61 -0
- package/dist/components/TNavbar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TNumberInput.cjs +2 -0
- package/dist/components/TNumberInput.cjs.map +1 -0
- package/dist/components/TNumberInput.js +7 -0
- package/dist/components/TNumberInput.js.map +1 -0
- package/dist/components/TNumberInput.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TNumberInput.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TNumberInput.vue_vue_type_script_setup_true_lang.js +145 -0
- package/dist/components/TNumberInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TPagination.cjs +2 -0
- package/dist/components/TPagination.cjs.map +1 -0
- package/dist/components/TPagination.js +7 -0
- package/dist/components/TPagination.js.map +1 -0
- package/dist/components/TPagination.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TPagination.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TPagination.vue_vue_type_script_setup_true_lang.js +105 -0
- package/dist/components/TPagination.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TPopover.cjs +2 -0
- package/dist/components/TPopover.cjs.map +1 -0
- package/dist/components/TPopover.js +7 -0
- package/dist/components/TPopover.js.map +1 -0
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.js +106 -0
- package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TPricing.cjs +2 -0
- package/dist/components/TPricing.cjs.map +1 -0
- package/dist/components/TPricing.js +7 -0
- package/dist/components/TPricing.js.map +1 -0
- package/dist/components/TPricing.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TPricing.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TPricing.vue_vue_type_script_setup_true_lang.js +33 -0
- package/dist/components/TPricing.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TPricingCard.cjs +2 -0
- package/dist/components/TPricingCard.cjs.map +1 -0
- package/dist/components/TPricingCard.js +7 -0
- package/dist/components/TPricingCard.js.map +1 -0
- package/dist/components/TPricingCard.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TPricingCard.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TPricingCard.vue_vue_type_script_setup_true_lang.js +93 -0
- package/dist/components/TPricingCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TProgress.cjs +2 -0
- package/dist/components/TProgress.cjs.map +1 -0
- package/dist/components/TProgress.js +7 -0
- package/dist/components/TProgress.js.map +1 -0
- package/dist/components/TProgress.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TProgress.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TProgress.vue_vue_type_script_setup_true_lang.js +33 -0
- package/dist/components/TProgress.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TRadio.cjs +2 -0
- package/dist/components/TRadio.cjs.map +1 -0
- package/dist/components/TRadio.js +7 -0
- package/dist/components/TRadio.js.map +1 -0
- package/dist/components/TRadio.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TRadio.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TRadio.vue_vue_type_script_setup_true_lang.js +73 -0
- package/dist/components/TRadio.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TRadioGroup.cjs +2 -0
- package/dist/components/TRadioGroup.cjs.map +1 -0
- package/dist/components/TRadioGroup.js +7 -0
- package/dist/components/TRadioGroup.js.map +1 -0
- package/dist/components/TRadioGroup.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TRadioGroup.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TRadioGroup.vue_vue_type_script_setup_true_lang.js +46 -0
- package/dist/components/TRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TSelect.cjs +2 -0
- package/dist/components/TSelect.cjs.map +1 -0
- package/dist/components/TSelect.js +7 -0
- package/dist/components/TSelect.js.map +1 -0
- package/dist/components/TSelect.vue.d.ts +2 -0
- package/dist/components/TSelect.vue.d.ts.map +1 -1
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.js +238 -0
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TSelectableList.cjs +2 -0
- package/dist/components/TSelectableList.cjs.map +1 -0
- package/dist/components/TSelectableList.js +7 -0
- package/dist/components/TSelectableList.js.map +1 -0
- package/dist/components/TSelectableList.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSelectableList.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSelectableList.vue_vue_type_script_setup_true_lang.js +133 -0
- package/dist/components/TSelectableList.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TSidebar.cjs +2 -0
- package/dist/components/TSidebar.cjs.map +1 -0
- package/dist/components/TSidebar.js +7 -0
- package/dist/components/TSidebar.js.map +1 -0
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js +98 -0
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TSkeleton.cjs +2 -0
- package/dist/components/TSkeleton.cjs.map +1 -0
- package/dist/components/TSkeleton.js +7 -0
- package/dist/components/TSkeleton.js.map +1 -0
- package/dist/components/TSkeleton.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSkeleton.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSkeleton.vue_vue_type_script_setup_true_lang.js +25 -0
- package/dist/components/TSkeleton.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TSpinner.cjs +2 -0
- package/dist/components/TSpinner.cjs.map +1 -0
- package/dist/components/TSpinner.js +7 -0
- package/dist/components/TSpinner.js.map +1 -0
- package/dist/components/TSpinner.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSpinner.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSpinner.vue_vue_type_script_setup_true_lang.js +24 -0
- package/dist/components/TSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TStack.cjs +2 -0
- package/dist/components/TStack.cjs.map +1 -0
- package/dist/components/TStack.js +7 -0
- package/dist/components/TStack.js.map +1 -0
- package/dist/components/TStack.vue.d.ts +1 -1
- package/dist/components/TStack.vue.d.ts.map +1 -1
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.js +50 -0
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TStat.cjs +2 -0
- package/dist/components/TStat.cjs.map +1 -0
- package/dist/components/TStat.js +7 -0
- package/dist/components/TStat.js.map +1 -0
- package/dist/components/TStat.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TStat.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TStat.vue_vue_type_script_setup_true_lang.js +72 -0
- package/dist/components/TStat.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TSteps.cjs +2 -0
- package/dist/components/TSteps.cjs.map +1 -0
- package/dist/components/TSteps.js +7 -0
- package/dist/components/TSteps.js.map +1 -0
- package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.js +83 -0
- package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TSwitch.cjs +2 -0
- package/dist/components/TSwitch.cjs.map +1 -0
- package/dist/components/TSwitch.js +7 -0
- package/dist/components/TSwitch.js.map +1 -0
- package/dist/components/TSwitch.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSwitch.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSwitch.vue_vue_type_script_setup_true_lang.js +71 -0
- package/dist/components/TSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTab.cjs +2 -0
- package/dist/components/TTab.cjs.map +1 -0
- package/dist/components/TTab.js +7 -0
- package/dist/components/TTab.js.map +1 -0
- package/dist/components/TTab.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTab.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTab.vue_vue_type_script_setup_true_lang.js +55 -0
- package/dist/components/TTab.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTabList.cjs +2 -0
- package/dist/components/TTabList.cjs.map +1 -0
- package/dist/components/TTabList.js +7 -0
- package/dist/components/TTabList.js.map +1 -0
- package/dist/components/TTabList.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTabList.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTabList.vue_vue_type_script_setup_true_lang.js +73 -0
- package/dist/components/TTabList.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTabPanel.cjs +2 -0
- package/dist/components/TTabPanel.cjs.map +1 -0
- package/dist/components/TTabPanel.js +7 -0
- package/dist/components/TTabPanel.js.map +1 -0
- package/dist/components/TTabPanel.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTabPanel.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTabPanel.vue_vue_type_script_setup_true_lang.js +24 -0
- package/dist/components/TTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTable.cjs +2 -0
- package/dist/components/TTable.cjs.map +1 -0
- package/dist/components/TTable.js +7 -0
- package/dist/components/TTable.js.map +1 -0
- package/dist/components/TTable.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTable.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTable.vue_vue_type_script_setup_true_lang.js +118 -0
- package/dist/components/TTable.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTabs.cjs +2 -0
- package/dist/components/TTabs.cjs.map +1 -0
- package/dist/components/TTabs.js +7 -0
- package/dist/components/TTabs.js.map +1 -0
- package/dist/components/TTabs.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTabs.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTabs.vue_vue_type_script_setup_true_lang.js +51 -0
- package/dist/components/TTabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTag.cjs +2 -0
- package/dist/components/TTag.cjs.map +1 -0
- package/dist/components/TTag.js +7 -0
- package/dist/components/TTag.js.map +1 -0
- package/dist/components/TTag.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTag.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTag.vue_vue_type_script_setup_true_lang.js +60 -0
- package/dist/components/TTag.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTextarea.cjs +2 -0
- package/dist/components/TTextarea.cjs.map +1 -0
- package/dist/components/TTextarea.js +7 -0
- package/dist/components/TTextarea.js.map +1 -0
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.js +81 -0
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTimeline.cjs +2 -0
- package/dist/components/TTimeline.cjs.map +1 -0
- package/dist/components/TTimeline.js +7 -0
- package/dist/components/TTimeline.js.map +1 -0
- package/dist/components/TTimeline.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTimeline.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTimeline.vue_vue_type_script_setup_true_lang.js +58 -0
- package/dist/components/TTimeline.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TToast.cjs +2 -0
- package/dist/components/TToast.cjs.map +1 -0
- package/dist/components/TToast.js +7 -0
- package/dist/components/TToast.js.map +1 -0
- package/dist/components/TToast.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TToast.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TToast.vue_vue_type_script_setup_true_lang.js +50 -0
- package/dist/components/TToast.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TToastProvider.cjs +2 -0
- package/dist/components/TToastProvider.cjs.map +1 -0
- package/dist/components/TToastProvider.js +7 -0
- package/dist/components/TToastProvider.js.map +1 -0
- package/dist/components/TToastProvider.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TToastProvider.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TToastProvider.vue_vue_type_script_setup_true_lang.js +33 -0
- package/dist/components/TToastProvider.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TToggleGroup.cjs +2 -0
- package/dist/components/TToggleGroup.cjs.map +1 -0
- package/dist/components/TToggleGroup.js +7 -0
- package/dist/components/TToggleGroup.js.map +1 -0
- package/dist/components/TToggleGroup.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TToggleGroup.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TToggleGroup.vue_vue_type_script_setup_true_lang.js +119 -0
- package/dist/components/TToggleGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTooltip.cjs +2 -0
- package/dist/components/TTooltip.cjs.map +1 -0
- package/dist/components/TTooltip.js +7 -0
- package/dist/components/TTooltip.js.map +1 -0
- package/dist/components/TTooltip.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTooltip.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTooltip.vue_vue_type_script_setup_true_lang.js +75 -0
- package/dist/components/TTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTreeView.cjs +2 -0
- package/dist/components/TTreeView.cjs.map +1 -0
- package/dist/components/TTreeView.js +7 -0
- package/dist/components/TTreeView.js.map +1 -0
- package/dist/components/TTreeView.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTreeView.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTreeView.vue_vue_type_script_setup_true_lang.js +161 -0
- package/dist/components/TTreeView.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTreeViewItem.cjs +2 -0
- package/dist/components/TTreeViewItem.cjs.map +1 -0
- package/dist/components/TTreeViewItem.js +7 -0
- package/dist/components/TTreeViewItem.js.map +1 -0
- package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.js +101 -0
- package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/accordion.cjs +2 -0
- package/dist/components/accordion.cjs.map +1 -0
- package/dist/components/accordion.js +6 -0
- package/dist/components/accordion.js.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/sidebar.cjs +2 -0
- package/dist/components/sidebar.cjs.map +1 -0
- package/dist/components/sidebar.js +6 -0
- package/dist/components/sidebar.js.map +1 -0
- package/dist/components/tabs-context.cjs +2 -0
- package/dist/components/tabs-context.cjs.map +1 -0
- package/dist/components/tabs-context.js +6 -0
- package/dist/components/tabs-context.js.map +1 -0
- package/dist/components/tree-view.cjs +2 -0
- package/dist/components/tree-view.cjs.map +1 -0
- package/dist/components/tree-view.js +6 -0
- package/dist/components/tree-view.js.map +1 -0
- package/dist/composables/useControllableOpen.cjs +2 -0
- package/dist/composables/useControllableOpen.cjs.map +1 -0
- package/dist/composables/useControllableOpen.js +15 -0
- package/dist/composables/useControllableOpen.js.map +1 -0
- package/dist/composables/useToast.cjs +2 -0
- package/dist/composables/useToast.cjs.map +1 -0
- package/dist/composables/useToast.js +41 -0
- package/dist/composables/useToast.js.map +1 -0
- package/dist/index.cjs +1 -12
- package/dist/index.js +66 -5992
- package/dist/plugin.cjs +2 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.js +135 -0
- package/dist/plugin.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/types/contracts.cjs +2 -0
- package/dist/types/contracts.cjs.map +1 -0
- package/dist/types/contracts.js +31 -0
- package/dist/types/contracts.js.map +1 -0
- package/package.json +5 -5
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { computed as e, createBlock as t, defineComponent as n, getCurrentInstance as r, mergeProps as i, openBlock as a, renderSlot as o, resolveDynamicComponent as s, withCtx as c } from "vue";
|
|
2
|
+
//#region src/components/TLink.vue?vue&type=script&setup=true&lang.ts
|
|
3
|
+
var l = /*@__PURE__*/ n({
|
|
4
|
+
__name: "TLink",
|
|
5
|
+
props: {
|
|
6
|
+
to: { default: void 0 },
|
|
7
|
+
href: { default: void 0 },
|
|
8
|
+
external: {
|
|
9
|
+
type: Boolean,
|
|
10
|
+
default: !1
|
|
11
|
+
},
|
|
12
|
+
disabled: {
|
|
13
|
+
type: Boolean,
|
|
14
|
+
default: !1
|
|
15
|
+
},
|
|
16
|
+
variant: { default: "default" }
|
|
17
|
+
},
|
|
18
|
+
setup(n) {
|
|
19
|
+
let l = n, u = r(), d = e(() => l.to ? u?.appContext.components.RouterLink ?? null : null), f = e(() => !!d.value), p = e(() => l.disabled ? "span" : l.to && d.value ? d.value : "a"), m = e(() => l.disabled ? {} : l.to && f.value ? { to: l.to } : {
|
|
20
|
+
href: l.href ?? (typeof l.to == "string" ? l.to : void 0),
|
|
21
|
+
...l.external ? {
|
|
22
|
+
target: "_blank",
|
|
23
|
+
rel: "noopener noreferrer"
|
|
24
|
+
} : {}
|
|
25
|
+
}), h = e(() => [
|
|
26
|
+
"t-link",
|
|
27
|
+
`t-link--${l.variant}`,
|
|
28
|
+
{ "is-disabled": l.disabled }
|
|
29
|
+
]);
|
|
30
|
+
return (e, r) => (a(), t(s(p.value), i(m.value, {
|
|
31
|
+
class: h.value,
|
|
32
|
+
"aria-disabled": n.disabled || void 0,
|
|
33
|
+
tabindex: n.disabled ? -1 : void 0
|
|
34
|
+
}), {
|
|
35
|
+
default: c(() => [o(e.$slots, "default")]),
|
|
36
|
+
_: 3
|
|
37
|
+
}, 16, [
|
|
38
|
+
"class",
|
|
39
|
+
"aria-disabled",
|
|
40
|
+
"tabindex"
|
|
41
|
+
]));
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
//#endregion
|
|
45
|
+
export { l as default };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=TLink.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TLink.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../src/components/TLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, type Component } from 'vue';\n\nexport type TLinkVariant = 'default' | 'muted' | 'danger';\n\nconst props = withDefaults(\n defineProps<{\n to?: string | Record<string, unknown>;\n href?: string;\n external?: boolean;\n disabled?: boolean;\n variant?: TLinkVariant;\n }>(),\n {\n to: undefined,\n href: undefined,\n external: false,\n disabled: false,\n variant: 'default',\n },\n);\n\nconst instance = getCurrentInstance();\n\nconst routerLinkComponent = computed<Component | null>(() => {\n if (!props.to) return null;\n\n return (instance?.appContext.components.RouterLink as Component | undefined) ?? null;\n});\n\nconst hasRouterLink = computed(() => {\n return Boolean(routerLinkComponent.value);\n});\n\nconst tag = computed<string | Component>(() => {\n if (props.disabled) return 'span';\n if (props.to && routerLinkComponent.value) return routerLinkComponent.value;\n return 'a';\n});\n\nconst linkProps = computed(() => {\n if (props.disabled) return {};\n if (props.to && hasRouterLink.value) return { to: props.to };\n const href = props.href ?? (typeof props.to === 'string' ? props.to : undefined);\n return {\n href,\n ...(props.external ? { target: '_blank', rel: 'noopener noreferrer' } : {}),\n };\n});\n\nconst classes = computed(() => [\n 't-link',\n `t-link--${props.variant}`,\n {\n 'is-disabled': props.disabled,\n },\n]);\n</script>\n\n<template>\n <component\n :is=\"tag\"\n v-bind=\"linkProps\"\n :class=\"classes\"\n :aria-disabled=\"disabled || undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n >\n <slot />\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAKA,IAAM,IAAQ,GAiBR,IAAW,EAAmB,GAE9B,IAAsB,QACrB,EAAM,KAEH,GAAU,WAAW,WAAW,cAAwC,OAF1D,IAGvB,GAEK,IAAgB,QACb,EAAQ,EAAoB,KACpC,GAEK,IAAM,QACN,EAAM,WAAiB,SACvB,EAAM,MAAM,EAAoB,QAAc,EAAoB,QAC/D,GACR,GAEK,IAAY,QACZ,EAAM,WAAiB,CAAC,IACxB,EAAM,MAAM,EAAc,QAAc,EAAE,IAAI,EAAM,GAAG,IAEpD;GACL,MAFW,EAAM,SAAS,OAAO,EAAM,MAAO,WAAW,EAAM,KAAK,KAAA;GAGpE,GAAI,EAAM,WAAW;IAAE,QAAQ;IAAU,KAAK;GAAsB,IAAI,CAAC;EAC3E,CACD,GAEK,IAAU,QAAe;GAC7B;GACA,WAAW,EAAM;GACjB,EACE,eAAe,EAAM,SACvB;EACF,CAAC;yBAIC,EAQY,EAPL,EAAA,KAAG,GADV,EAEU,EAME,OANO;GAChB,OAAO,EAAA;GACP,iBAAe,EAAA,YAAY,KAAA;GAC3B,UAAU,EAAA,WAAQ,KAAQ,KAAA;;oBAEnB,CAAR,EAAQ,EAAA,QAAA,SAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TMarkdownEditor.cjs","names":[],"sources":["../../src/components/TMarkdownEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, nextTick } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n size?: TSize;\n disabled?: boolean;\n placeholder?: string;\n uploadImage?: (file: File) => Promise<string>;\n }>(),\n {\n modelValue: '',\n size: 'md',\n disabled: false,\n placeholder: 'Write your markdown here...',\n uploadImage: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'image-upload': [file: File, url: string];\n 'image-upload-error': [file: File, error: Error];\n}>();\n\ndefineSlots<{\n toolbar?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst textareaRef = ref<HTMLTextAreaElement | null>(null);\nconst isUploading = ref(false);\n\nconst rootClasses = computed(() => [\n 't-md-editor',\n `t-md-editor--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-uploading': isUploading.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst editorAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst stringValue = computed(() => `${props.modelValue ?? ''}`);\n\nconst onInput = (event: Event) => {\n emit('update:modelValue', (event.target as HTMLTextAreaElement).value);\n};\n\n/* ──────── Toolbar Actions ──────── */\n\nconst insertAtCursor = (before: string, after = '') => {\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const end = el.selectionEnd;\n const text = stringValue.value;\n const selected = text.slice(start, end);\n\n const newText = text.slice(0, start) + before + selected + after + text.slice(end);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n const cursorPos = selected\n ? start + before.length + selected.length + after.length\n : start + before.length;\n el.setSelectionRange(cursorPos, cursorPos);\n });\n};\n\nconst insertHeading = (level: number) => {\n const prefix = '#'.repeat(level) + ' ';\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const text = stringValue.value;\n\n // Find start of current line\n const lineStart = text.lastIndexOf('\\n', start - 1) + 1;\n const lineEnd = text.indexOf('\\n', start);\n const actualEnd = lineEnd === -1 ? text.length : lineEnd;\n const line = text.slice(lineStart, actualEnd);\n\n // Strip existing heading markers\n const stripped = line.replace(/^#{1,6}\\s*/, '');\n const newLine = prefix + stripped;\n\n const newText = text.slice(0, lineStart) + newLine + text.slice(actualEnd);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n el.setSelectionRange(lineStart + newLine.length, lineStart + newLine.length);\n });\n};\n\nconst insertBold = () => insertAtCursor('**', '**');\nconst insertItalic = () => insertAtCursor('_', '_');\nconst insertCode = () => insertAtCursor('`', '`');\nconst insertCodeBlock = () => insertAtCursor('\\n```\\n', '\\n```\\n');\nconst insertLink = () => insertAtCursor('[', '](url)');\nconst insertList = () => insertAtCursor('\\n- ');\nconst insertOrderedList = () => insertAtCursor('\\n1. ');\nconst insertQuote = () => insertAtCursor('\\n> ');\nconst insertHr = () => insertAtCursor('\\n---\\n');\n\n/* ──────── Markdown → HTML rendering ──────── */\n\nconst renderedHtml = computed(() => {\n return markdownToHtml(stringValue.value);\n});\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction markdownToHtml(md: string): string {\n if (!md) return '';\n\n const lines = md.split('\\n');\n const html: string[] = [];\n let inCodeBlock = false;\n let inList = false;\n let inOrderedList = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Code blocks\n if (line.trim().startsWith('```')) {\n if (inCodeBlock) {\n html.push('</code></pre>');\n inCodeBlock = false;\n } else {\n inCodeBlock = true;\n html.push('<pre class=\"t-md-editor__code-block\"><code>');\n }\n continue;\n }\n\n if (inCodeBlock) {\n html.push(escapeHtml(line));\n html.push('\\n');\n continue;\n }\n\n // Close open lists if needed\n const isUnorderedListItem = /^[-*+]\\s/.test(line.trim());\n const isOrderedListItem = /^\\d+\\.\\s/.test(line.trim());\n\n if (inList && !isUnorderedListItem) {\n html.push('</ul>');\n inList = false;\n }\n if (inOrderedList && !isOrderedListItem) {\n html.push('</ol>');\n inOrderedList = false;\n }\n\n // Horizontal rule\n if (/^(-{3,}|_{3,}|\\*{3,})$/.test(line.trim())) {\n html.push('<hr class=\"t-md-editor__hr\" />');\n continue;\n }\n\n // Headings\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n const level = headingMatch[1].length;\n html.push(`<h${level} class=\"t-md-editor__heading t-md-editor__heading--${level}\">${inlineMarkdown(escapeHtml(headingMatch[2]))}</h${level}>`);\n continue;\n }\n\n // Blockquote\n if (line.trim().startsWith('> ')) {\n html.push(`<blockquote class=\"t-md-editor__blockquote\">${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</blockquote>`);\n continue;\n }\n\n // Unordered list\n if (isUnorderedListItem) {\n if (!inList) {\n html.push('<ul class=\"t-md-editor__list\">');\n inList = true;\n }\n html.push(`<li>${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</li>`);\n continue;\n }\n\n // Ordered list\n if (isOrderedListItem) {\n if (!inOrderedList) {\n html.push('<ol class=\"t-md-editor__list t-md-editor__list--ordered\">');\n inOrderedList = true;\n }\n const content = line.trim().replace(/^\\d+\\.\\s/, '');\n html.push(`<li>${inlineMarkdown(escapeHtml(content))}</li>`);\n continue;\n }\n\n // Empty line\n if (line.trim() === '') {\n html.push('<br />');\n continue;\n }\n\n // Paragraph\n html.push(`<p class=\"t-md-editor__paragraph\">${inlineMarkdown(escapeHtml(line))}</p>`);\n }\n\n // Close any open blocks\n if (inCodeBlock) html.push('</code></pre>');\n if (inList) html.push('</ul>');\n if (inOrderedList) html.push('</ol>');\n\n return html.join('\\n');\n}\n\nfunction inlineMarkdown(text: string): string {\n // Images: \n text = text.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '<img src=\"$2\" alt=\"$1\" class=\"t-md-editor__image\" loading=\"lazy\" />');\n // Links: [text](url)\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>');\n // Bold: **text**\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n // Italic: _text_ or *text*\n text = text.replace(/_(.+?)_/g, '<em>$1</em>');\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, '<em>$1</em>');\n // Inline code: `text`\n text = text.replace(/`(.+?)`/g, '<code class=\"t-md-editor__inline-code\">$1</code>');\n // Strikethrough: ~~text~~\n text = text.replace(/~~(.+?)~~/g, '<del>$1</del>');\n return text;\n}\n\n/* ──────── Image paste / drop handling ──────── */\n\nconst handlePaste = async (event: ClipboardEvent) => {\n if (props.disabled) return;\n\n const items = event.clipboardData?.items;\n if (!items) return;\n\n for (const item of items) {\n if (item.type.startsWith('image/')) {\n event.preventDefault();\n const file = item.getAsFile();\n if (file) await processImageUpload(file);\n return;\n }\n }\n};\n\nconst handleDrop = async (event: DragEvent) => {\n if (props.disabled) return;\n\n const files = event.dataTransfer?.files;\n if (!files) return;\n\n for (const file of files) {\n if (file.type.startsWith('image/')) {\n event.preventDefault();\n await processImageUpload(file);\n }\n }\n};\n\nconst handleDragOver = (event: DragEvent) => {\n if (props.disabled) return;\n event.preventDefault();\n};\n\nconst processImageUpload = async (file: File) => {\n if (!props.uploadImage) {\n // Fallback: insert a placeholder with the file name\n insertAtCursor(`![${file.name}]()`);\n return;\n }\n\n // Insert uploading placeholder\n const placeholder = `![Uploading ${file.name}...]()`;\n insertAtCursor(placeholder);\n isUploading.value = true;\n\n try {\n const url = props.uploadImage(file);\n const resolvedUrl = url instanceof Promise ? await url : url;\n\n // Replace placeholder with actual URL\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, ``);\n emit('update:modelValue', newValue);\n emit('image-upload', file, resolvedUrl);\n } catch (err) {\n // Remove placeholder on error\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, '');\n emit('update:modelValue', newValue);\n emit('image-upload-error', file, err instanceof Error ? err : new Error(String(err)));\n } finally {\n isUploading.value = false;\n }\n};\n\n/* ──────── Keyboard shortcuts ──────── */\n\nconst handleKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n const mod = event.metaKey || event.ctrlKey;\n if (!mod) return;\n\n switch (event.key) {\n case 'b':\n event.preventDefault();\n insertBold();\n break;\n case 'i':\n event.preventDefault();\n insertItalic();\n break;\n case 'k':\n event.preventDefault();\n insertLink();\n break;\n case 'e':\n event.preventDefault();\n insertCode();\n break;\n }\n};\n\n</script>\n\n<template>\n <div\n v-bind=\"editorAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <!-- Toolbar -->\n <div\n class=\"t-md-editor__toolbar\"\n role=\"toolbar\"\n aria-label=\"Markdown formatting\"\n >\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 1 (H1)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(1)\"\n >\n H1\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 2 (H2)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(2)\"\n >\n H2\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 3 (H3)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(3)\"\n >\n H3\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Bold (Ctrl+B)\"\n :disabled=\"disabled\"\n @click=\"insertBold\"\n >\n <strong>B</strong>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Italic (Ctrl+I)\"\n :disabled=\"disabled\"\n @click=\"insertItalic\"\n >\n <em>I</em>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Strikethrough\"\n :disabled=\"disabled\"\n @click=\"insertAtCursor('~~', '~~')\"\n >\n <del>S</del>\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Inline code (Ctrl+E)\"\n :disabled=\"disabled\"\n @click=\"insertCode\"\n >\n </>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Code block\"\n :disabled=\"disabled\"\n @click=\"insertCodeBlock\"\n >\n { }\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Link (Ctrl+K)\"\n :disabled=\"disabled\"\n @click=\"insertLink\"\n >\n 🔗\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Unordered list\"\n :disabled=\"disabled\"\n @click=\"insertList\"\n >\n • List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Ordered list\"\n :disabled=\"disabled\"\n @click=\"insertOrderedList\"\n >\n 1. List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Blockquote\"\n :disabled=\"disabled\"\n @click=\"insertQuote\"\n >\n >\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Horizontal rule\"\n :disabled=\"disabled\"\n @click=\"insertHr\"\n >\n ―\n </button>\n </div>\n\n <slot name=\"toolbar\" />\n </div>\n\n <!-- Editor body -->\n <div class=\"t-md-editor__body\">\n <!-- Write pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--write\"\n >\n <textarea\n ref=\"textareaRef\"\n class=\"t-md-editor__textarea\"\n :value=\"stringValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-label=\"placeholder\"\n @input=\"onInput\"\n @paste=\"handlePaste\"\n @drop=\"handleDrop\"\n @dragover=\"handleDragOver\"\n @keydown=\"handleKeydown\"\n />\n </div>\n\n <!-- Preview pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--preview\"\n aria-label=\"Markdown preview\"\n >\n <!-- eslint-disable vue/no-v-html -->\n <div\n class=\"t-md-editor__preview\"\n v-html=\"renderedHtml\"\n />\n <!-- eslint-enable vue/no-v-html -->\n </div>\n </div>\n\n <!-- Upload indicator -->\n <div\n v-if=\"isUploading\"\n class=\"t-md-editor__upload-bar\"\n role=\"status\"\n aria-live=\"polite\"\n >\n Uploading image…\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TMarkdownEditor.js","names":[],"sources":["../../src/components/TMarkdownEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, nextTick } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n size?: TSize;\n disabled?: boolean;\n placeholder?: string;\n uploadImage?: (file: File) => Promise<string>;\n }>(),\n {\n modelValue: '',\n size: 'md',\n disabled: false,\n placeholder: 'Write your markdown here...',\n uploadImage: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'image-upload': [file: File, url: string];\n 'image-upload-error': [file: File, error: Error];\n}>();\n\ndefineSlots<{\n toolbar?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst textareaRef = ref<HTMLTextAreaElement | null>(null);\nconst isUploading = ref(false);\n\nconst rootClasses = computed(() => [\n 't-md-editor',\n `t-md-editor--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-uploading': isUploading.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst editorAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst stringValue = computed(() => `${props.modelValue ?? ''}`);\n\nconst onInput = (event: Event) => {\n emit('update:modelValue', (event.target as HTMLTextAreaElement).value);\n};\n\n/* ──────── Toolbar Actions ──────── */\n\nconst insertAtCursor = (before: string, after = '') => {\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const end = el.selectionEnd;\n const text = stringValue.value;\n const selected = text.slice(start, end);\n\n const newText = text.slice(0, start) + before + selected + after + text.slice(end);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n const cursorPos = selected\n ? start + before.length + selected.length + after.length\n : start + before.length;\n el.setSelectionRange(cursorPos, cursorPos);\n });\n};\n\nconst insertHeading = (level: number) => {\n const prefix = '#'.repeat(level) + ' ';\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const text = stringValue.value;\n\n // Find start of current line\n const lineStart = text.lastIndexOf('\\n', start - 1) + 1;\n const lineEnd = text.indexOf('\\n', start);\n const actualEnd = lineEnd === -1 ? text.length : lineEnd;\n const line = text.slice(lineStart, actualEnd);\n\n // Strip existing heading markers\n const stripped = line.replace(/^#{1,6}\\s*/, '');\n const newLine = prefix + stripped;\n\n const newText = text.slice(0, lineStart) + newLine + text.slice(actualEnd);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n el.setSelectionRange(lineStart + newLine.length, lineStart + newLine.length);\n });\n};\n\nconst insertBold = () => insertAtCursor('**', '**');\nconst insertItalic = () => insertAtCursor('_', '_');\nconst insertCode = () => insertAtCursor('`', '`');\nconst insertCodeBlock = () => insertAtCursor('\\n```\\n', '\\n```\\n');\nconst insertLink = () => insertAtCursor('[', '](url)');\nconst insertList = () => insertAtCursor('\\n- ');\nconst insertOrderedList = () => insertAtCursor('\\n1. ');\nconst insertQuote = () => insertAtCursor('\\n> ');\nconst insertHr = () => insertAtCursor('\\n---\\n');\n\n/* ──────── Markdown → HTML rendering ──────── */\n\nconst renderedHtml = computed(() => {\n return markdownToHtml(stringValue.value);\n});\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction markdownToHtml(md: string): string {\n if (!md) return '';\n\n const lines = md.split('\\n');\n const html: string[] = [];\n let inCodeBlock = false;\n let inList = false;\n let inOrderedList = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Code blocks\n if (line.trim().startsWith('```')) {\n if (inCodeBlock) {\n html.push('</code></pre>');\n inCodeBlock = false;\n } else {\n inCodeBlock = true;\n html.push('<pre class=\"t-md-editor__code-block\"><code>');\n }\n continue;\n }\n\n if (inCodeBlock) {\n html.push(escapeHtml(line));\n html.push('\\n');\n continue;\n }\n\n // Close open lists if needed\n const isUnorderedListItem = /^[-*+]\\s/.test(line.trim());\n const isOrderedListItem = /^\\d+\\.\\s/.test(line.trim());\n\n if (inList && !isUnorderedListItem) {\n html.push('</ul>');\n inList = false;\n }\n if (inOrderedList && !isOrderedListItem) {\n html.push('</ol>');\n inOrderedList = false;\n }\n\n // Horizontal rule\n if (/^(-{3,}|_{3,}|\\*{3,})$/.test(line.trim())) {\n html.push('<hr class=\"t-md-editor__hr\" />');\n continue;\n }\n\n // Headings\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n const level = headingMatch[1].length;\n html.push(`<h${level} class=\"t-md-editor__heading t-md-editor__heading--${level}\">${inlineMarkdown(escapeHtml(headingMatch[2]))}</h${level}>`);\n continue;\n }\n\n // Blockquote\n if (line.trim().startsWith('> ')) {\n html.push(`<blockquote class=\"t-md-editor__blockquote\">${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</blockquote>`);\n continue;\n }\n\n // Unordered list\n if (isUnorderedListItem) {\n if (!inList) {\n html.push('<ul class=\"t-md-editor__list\">');\n inList = true;\n }\n html.push(`<li>${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</li>`);\n continue;\n }\n\n // Ordered list\n if (isOrderedListItem) {\n if (!inOrderedList) {\n html.push('<ol class=\"t-md-editor__list t-md-editor__list--ordered\">');\n inOrderedList = true;\n }\n const content = line.trim().replace(/^\\d+\\.\\s/, '');\n html.push(`<li>${inlineMarkdown(escapeHtml(content))}</li>`);\n continue;\n }\n\n // Empty line\n if (line.trim() === '') {\n html.push('<br />');\n continue;\n }\n\n // Paragraph\n html.push(`<p class=\"t-md-editor__paragraph\">${inlineMarkdown(escapeHtml(line))}</p>`);\n }\n\n // Close any open blocks\n if (inCodeBlock) html.push('</code></pre>');\n if (inList) html.push('</ul>');\n if (inOrderedList) html.push('</ol>');\n\n return html.join('\\n');\n}\n\nfunction inlineMarkdown(text: string): string {\n // Images: \n text = text.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '<img src=\"$2\" alt=\"$1\" class=\"t-md-editor__image\" loading=\"lazy\" />');\n // Links: [text](url)\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>');\n // Bold: **text**\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n // Italic: _text_ or *text*\n text = text.replace(/_(.+?)_/g, '<em>$1</em>');\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, '<em>$1</em>');\n // Inline code: `text`\n text = text.replace(/`(.+?)`/g, '<code class=\"t-md-editor__inline-code\">$1</code>');\n // Strikethrough: ~~text~~\n text = text.replace(/~~(.+?)~~/g, '<del>$1</del>');\n return text;\n}\n\n/* ──────── Image paste / drop handling ──────── */\n\nconst handlePaste = async (event: ClipboardEvent) => {\n if (props.disabled) return;\n\n const items = event.clipboardData?.items;\n if (!items) return;\n\n for (const item of items) {\n if (item.type.startsWith('image/')) {\n event.preventDefault();\n const file = item.getAsFile();\n if (file) await processImageUpload(file);\n return;\n }\n }\n};\n\nconst handleDrop = async (event: DragEvent) => {\n if (props.disabled) return;\n\n const files = event.dataTransfer?.files;\n if (!files) return;\n\n for (const file of files) {\n if (file.type.startsWith('image/')) {\n event.preventDefault();\n await processImageUpload(file);\n }\n }\n};\n\nconst handleDragOver = (event: DragEvent) => {\n if (props.disabled) return;\n event.preventDefault();\n};\n\nconst processImageUpload = async (file: File) => {\n if (!props.uploadImage) {\n // Fallback: insert a placeholder with the file name\n insertAtCursor(`![${file.name}]()`);\n return;\n }\n\n // Insert uploading placeholder\n const placeholder = `![Uploading ${file.name}...]()`;\n insertAtCursor(placeholder);\n isUploading.value = true;\n\n try {\n const url = props.uploadImage(file);\n const resolvedUrl = url instanceof Promise ? await url : url;\n\n // Replace placeholder with actual URL\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, ``);\n emit('update:modelValue', newValue);\n emit('image-upload', file, resolvedUrl);\n } catch (err) {\n // Remove placeholder on error\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, '');\n emit('update:modelValue', newValue);\n emit('image-upload-error', file, err instanceof Error ? err : new Error(String(err)));\n } finally {\n isUploading.value = false;\n }\n};\n\n/* ──────── Keyboard shortcuts ──────── */\n\nconst handleKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n const mod = event.metaKey || event.ctrlKey;\n if (!mod) return;\n\n switch (event.key) {\n case 'b':\n event.preventDefault();\n insertBold();\n break;\n case 'i':\n event.preventDefault();\n insertItalic();\n break;\n case 'k':\n event.preventDefault();\n insertLink();\n break;\n case 'e':\n event.preventDefault();\n insertCode();\n break;\n }\n};\n\n</script>\n\n<template>\n <div\n v-bind=\"editorAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <!-- Toolbar -->\n <div\n class=\"t-md-editor__toolbar\"\n role=\"toolbar\"\n aria-label=\"Markdown formatting\"\n >\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 1 (H1)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(1)\"\n >\n H1\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 2 (H2)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(2)\"\n >\n H2\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 3 (H3)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(3)\"\n >\n H3\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Bold (Ctrl+B)\"\n :disabled=\"disabled\"\n @click=\"insertBold\"\n >\n <strong>B</strong>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Italic (Ctrl+I)\"\n :disabled=\"disabled\"\n @click=\"insertItalic\"\n >\n <em>I</em>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Strikethrough\"\n :disabled=\"disabled\"\n @click=\"insertAtCursor('~~', '~~')\"\n >\n <del>S</del>\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Inline code (Ctrl+E)\"\n :disabled=\"disabled\"\n @click=\"insertCode\"\n >\n </>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Code block\"\n :disabled=\"disabled\"\n @click=\"insertCodeBlock\"\n >\n { }\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Link (Ctrl+K)\"\n :disabled=\"disabled\"\n @click=\"insertLink\"\n >\n 🔗\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Unordered list\"\n :disabled=\"disabled\"\n @click=\"insertList\"\n >\n • List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Ordered list\"\n :disabled=\"disabled\"\n @click=\"insertOrderedList\"\n >\n 1. List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Blockquote\"\n :disabled=\"disabled\"\n @click=\"insertQuote\"\n >\n >\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Horizontal rule\"\n :disabled=\"disabled\"\n @click=\"insertHr\"\n >\n ―\n </button>\n </div>\n\n <slot name=\"toolbar\" />\n </div>\n\n <!-- Editor body -->\n <div class=\"t-md-editor__body\">\n <!-- Write pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--write\"\n >\n <textarea\n ref=\"textareaRef\"\n class=\"t-md-editor__textarea\"\n :value=\"stringValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-label=\"placeholder\"\n @input=\"onInput\"\n @paste=\"handlePaste\"\n @drop=\"handleDrop\"\n @dragover=\"handleDragOver\"\n @keydown=\"handleKeydown\"\n />\n </div>\n\n <!-- Preview pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--preview\"\n aria-label=\"Markdown preview\"\n >\n <!-- eslint-disable vue/no-v-html -->\n <div\n class=\"t-md-editor__preview\"\n v-html=\"renderedHtml\"\n />\n <!-- eslint-enable vue/no-v-html -->\n </div>\n </div>\n\n <!-- Upload indicator -->\n <div\n v-if=\"isUploading\"\n class=\"t-md-editor__upload-bar\"\n role=\"status\"\n aria-live=\"polite\"\n >\n Uploading image…\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
let e=require("vue");var t={class:`t-md-editor__toolbar`,role:`toolbar`,"aria-label":`Markdown formatting`},n={class:`t-md-editor__toolbar-group`},r=[`disabled`],i=[`disabled`],a=[`disabled`],o={class:`t-md-editor__toolbar-group`},s=[`disabled`],c=[`disabled`],l=[`disabled`],u={class:`t-md-editor__toolbar-group`},d=[`disabled`],f=[`disabled`],p=[`disabled`],m={class:`t-md-editor__toolbar-group`},h=[`disabled`],g=[`disabled`],_=[`disabled`],ee=[`disabled`],v={class:`t-md-editor__body`},y={class:`t-md-editor__pane t-md-editor__pane--write`},b=[`value`,`placeholder`,`disabled`,`aria-label`],x={class:`t-md-editor__pane t-md-editor__pane--preview`,"aria-label":`Markdown preview`},S=[`innerHTML`],C={key:0,class:`t-md-editor__upload-bar`,role:`status`,"aria-live":`polite`},w=(0,e.defineComponent)({inheritAttrs:!1,__name:`TMarkdownEditor`,props:{modelValue:{default:``},size:{default:`md`},disabled:{type:Boolean,default:!1},placeholder:{default:`Write your markdown here...`},uploadImage:{type:Function,default:void 0}},emits:[`update:modelValue`,`image-upload`,`image-upload-error`],setup(w,{emit:T}){let E=w,D=T,O=(0,e.useAttrs)(),k=(0,e.ref)(null),A=(0,e.ref)(!1),j=(0,e.computed)(()=>[`t-md-editor`,`t-md-editor--${E.size}`,{"is-disabled":E.disabled,"is-uploading":A.value},O.class]),M=(0,e.computed)(()=>O.style),N=(0,e.computed)(()=>{let{class:e,style:t,...n}=O;return n}),P=(0,e.computed)(()=>`${E.modelValue??``}`),F=e=>{D(`update:modelValue`,e.target.value)},I=(t,n=``)=>{let r=k.value;if(!r)return;let i=r.selectionStart,a=r.selectionEnd,o=P.value,s=o.slice(i,a),c=o.slice(0,i)+t+s+n+o.slice(a);D(`update:modelValue`,c),(0,e.nextTick)(()=>{r.focus();let e=s?i+t.length+s.length+n.length:i+t.length;r.setSelectionRange(e,e)})},L=t=>{let n=`#`.repeat(t)+` `,r=k.value;if(!r)return;let i=r.selectionStart,a=P.value,o=a.lastIndexOf(`
|
|
2
|
+
`,i-1)+1,s=a.indexOf(`
|
|
3
|
+
`,i),c=s===-1?a.length:s,l=n+a.slice(o,c).replace(/^#{1,6}\s*/,``),u=a.slice(0,o)+l+a.slice(c);D(`update:modelValue`,u),(0,e.nextTick)(()=>{r.focus(),r.setSelectionRange(o+l.length,o+l.length)})},R=()=>I(`**`,`**`),z=()=>I(`_`,`_`),B=()=>I("`","`"),V=()=>I("\n```\n","\n```\n"),H=()=>I(`[`,`](url)`),U=()=>I(`
|
|
4
|
+
- `),W=()=>I(`
|
|
5
|
+
1. `),G=()=>I(`
|
|
6
|
+
> `),K=()=>I(`
|
|
7
|
+
---
|
|
8
|
+
`),q=(0,e.computed)(()=>Y(P.value));function J(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`)}function Y(e){if(!e)return``;let t=e.split(`
|
|
9
|
+
`),n=[],r=!1,i=!1,a=!1;for(let e=0;e<t.length;e++){let o=t[e];if(o.trim().startsWith("```")){r?(n.push(`</code></pre>`),r=!1):(r=!0,n.push(`<pre class="t-md-editor__code-block"><code>`));continue}if(r){n.push(J(o)),n.push(`
|
|
10
|
+
`);continue}let s=/^[-*+]\s/.test(o.trim()),c=/^\d+\.\s/.test(o.trim());if(i&&!s&&(n.push(`</ul>`),i=!1),a&&!c&&(n.push(`</ol>`),a=!1),/^(-{3,}|_{3,}|\*{3,})$/.test(o.trim())){n.push(`<hr class="t-md-editor__hr" />`);continue}let l=o.match(/^(#{1,6})\s+(.+)$/);if(l){let e=l[1].length;n.push(`<h${e} class="t-md-editor__heading t-md-editor__heading--${e}">${X(J(l[2]))}</h${e}>`);continue}if(o.trim().startsWith(`> `)){n.push(`<blockquote class="t-md-editor__blockquote">${X(J(o.trim().slice(2)))}</blockquote>`);continue}if(s){i||=(n.push(`<ul class="t-md-editor__list">`),!0),n.push(`<li>${X(J(o.trim().slice(2)))}</li>`);continue}if(c){a||=(n.push(`<ol class="t-md-editor__list t-md-editor__list--ordered">`),!0);let e=o.trim().replace(/^\d+\.\s/,``);n.push(`<li>${X(J(e))}</li>`);continue}if(o.trim()===``){n.push(`<br />`);continue}n.push(`<p class="t-md-editor__paragraph">${X(J(o))}</p>`)}return r&&n.push(`</code></pre>`),i&&n.push(`</ul>`),a&&n.push(`</ol>`),n.join(`
|
|
11
|
+
`)}function X(e){return e=e.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,`<img src="$2" alt="$1" class="t-md-editor__image" loading="lazy" />`),e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,`<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>`),e=e.replace(/\*\*(.+?)\*\*/g,`<strong>$1</strong>`),e=e.replace(/_(.+?)_/g,`<em>$1</em>`),e=e.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,`<em>$1</em>`),e=e.replace(/`(.+?)`/g,`<code class="t-md-editor__inline-code">$1</code>`),e=e.replace(/~~(.+?)~~/g,`<del>$1</del>`),e}let Z=async e=>{if(E.disabled)return;let t=e.clipboardData?.items;if(t){for(let n of t)if(n.type.startsWith(`image/`)){e.preventDefault();let t=n.getAsFile();t&&await $(t);return}}},Q=async e=>{if(E.disabled)return;let t=e.dataTransfer?.files;if(t)for(let n of t)n.type.startsWith(`image/`)&&(e.preventDefault(),await $(n))},te=e=>{E.disabled||e.preventDefault()},$=async e=>{if(!E.uploadImage){I(`![${e.name}]()`);return}let t=`![Uploading ${e.name}...]()`;I(t),A.value=!0;try{let n=E.uploadImage(e),r=n instanceof Promise?await n:n,i=P.value.replace(t,``);D(`update:modelValue`,i),D(`image-upload`,e,r)}catch(n){let r=P.value.replace(t,``);D(`update:modelValue`,r),D(`image-upload-error`,e,n instanceof Error?n:Error(String(n)))}finally{A.value=!1}},ne=e=>{if(!E.disabled&&(e.metaKey||e.ctrlKey))switch(e.key){case`b`:e.preventDefault(),R();break;case`i`:e.preventDefault(),z();break;case`k`:e.preventDefault(),H();break;case`e`:e.preventDefault(),B();break}};return(T,E)=>((0,e.openBlock)(),(0,e.createElementBlock)(`div`,(0,e.mergeProps)(N.value,{class:j.value,style:M.value}),[(0,e.createElementVNode)(`div`,t,[(0,e.createElementVNode)(`div`,n,[(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Heading 1 (H1)`,disabled:w.disabled,onClick:E[0]||=e=>L(1)},` H1 `,8,r),(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Heading 2 (H2)`,disabled:w.disabled,onClick:E[1]||=e=>L(2)},` H2 `,8,i),(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Heading 3 (H3)`,disabled:w.disabled,onClick:E[2]||=e=>L(3)},` H3 `,8,a)]),E[7]||=(0,e.createElementVNode)(`div`,{class:`t-md-editor__toolbar-divider`,role:`separator`},null,-1),(0,e.createElementVNode)(`div`,o,[(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Bold (Ctrl+B)`,disabled:w.disabled,onClick:R},[...E[4]||=[(0,e.createElementVNode)(`strong`,null,`B`,-1)]],8,s),(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Italic (Ctrl+I)`,disabled:w.disabled,onClick:z},[...E[5]||=[(0,e.createElementVNode)(`em`,null,`I`,-1)]],8,c),(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Strikethrough`,disabled:w.disabled,onClick:E[3]||=e=>I(`~~`,`~~`)},[...E[6]||=[(0,e.createElementVNode)(`del`,null,`S`,-1)]],8,l)]),E[8]||=(0,e.createElementVNode)(`div`,{class:`t-md-editor__toolbar-divider`,role:`separator`},null,-1),(0,e.createElementVNode)(`div`,u,[(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Inline code (Ctrl+E)`,disabled:w.disabled,onClick:B},` </> `,8,d),(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Code block`,disabled:w.disabled,onClick:V},` { } `,8,f),(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Link (Ctrl+K)`,disabled:w.disabled,onClick:H},` 🔗 `,8,p)]),E[9]||=(0,e.createElementVNode)(`div`,{class:`t-md-editor__toolbar-divider`,role:`separator`},null,-1),(0,e.createElementVNode)(`div`,m,[(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Unordered list`,disabled:w.disabled,onClick:U},` •\xA0List `,8,h),(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Ordered list`,disabled:w.disabled,onClick:W},` 1.\xA0List `,8,g),(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Blockquote`,disabled:w.disabled,onClick:G},` > `,8,_),(0,e.createElementVNode)(`button`,{type:`button`,class:`t-md-editor__toolbar-btn`,title:`Horizontal rule`,disabled:w.disabled,onClick:K},` ― `,8,ee)]),(0,e.renderSlot)(T.$slots,`toolbar`)]),(0,e.createElementVNode)(`div`,v,[(0,e.createElementVNode)(`div`,y,[(0,e.createElementVNode)(`textarea`,{ref_key:`textareaRef`,ref:k,class:`t-md-editor__textarea`,value:P.value,placeholder:w.placeholder,disabled:w.disabled,"aria-label":w.placeholder,onInput:F,onPaste:Z,onDrop:Q,onDragover:te,onKeydown:ne},null,40,b)]),(0,e.createElementVNode)(`div`,x,[(0,e.createElementVNode)(`div`,{class:`t-md-editor__preview`,innerHTML:q.value},null,8,S)])]),A.value?((0,e.openBlock)(),(0,e.createElementBlock)(`div`,C,` Uploading image… `)):(0,e.createCommentVNode)(``,!0)],16))}});exports.default=w;
|
|
12
|
+
//# sourceMappingURL=TMarkdownEditor.vue_vue_type_script_setup_true_lang.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TMarkdownEditor.vue_vue_type_script_setup_true_lang.cjs","names":[],"sources":["../../src/components/TMarkdownEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, nextTick } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n size?: TSize;\n disabled?: boolean;\n placeholder?: string;\n uploadImage?: (file: File) => Promise<string>;\n }>(),\n {\n modelValue: '',\n size: 'md',\n disabled: false,\n placeholder: 'Write your markdown here...',\n uploadImage: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'image-upload': [file: File, url: string];\n 'image-upload-error': [file: File, error: Error];\n}>();\n\ndefineSlots<{\n toolbar?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst textareaRef = ref<HTMLTextAreaElement | null>(null);\nconst isUploading = ref(false);\n\nconst rootClasses = computed(() => [\n 't-md-editor',\n `t-md-editor--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-uploading': isUploading.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst editorAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst stringValue = computed(() => `${props.modelValue ?? ''}`);\n\nconst onInput = (event: Event) => {\n emit('update:modelValue', (event.target as HTMLTextAreaElement).value);\n};\n\n/* ──────── Toolbar Actions ──────── */\n\nconst insertAtCursor = (before: string, after = '') => {\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const end = el.selectionEnd;\n const text = stringValue.value;\n const selected = text.slice(start, end);\n\n const newText = text.slice(0, start) + before + selected + after + text.slice(end);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n const cursorPos = selected\n ? start + before.length + selected.length + after.length\n : start + before.length;\n el.setSelectionRange(cursorPos, cursorPos);\n });\n};\n\nconst insertHeading = (level: number) => {\n const prefix = '#'.repeat(level) + ' ';\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const text = stringValue.value;\n\n // Find start of current line\n const lineStart = text.lastIndexOf('\\n', start - 1) + 1;\n const lineEnd = text.indexOf('\\n', start);\n const actualEnd = lineEnd === -1 ? text.length : lineEnd;\n const line = text.slice(lineStart, actualEnd);\n\n // Strip existing heading markers\n const stripped = line.replace(/^#{1,6}\\s*/, '');\n const newLine = prefix + stripped;\n\n const newText = text.slice(0, lineStart) + newLine + text.slice(actualEnd);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n el.setSelectionRange(lineStart + newLine.length, lineStart + newLine.length);\n });\n};\n\nconst insertBold = () => insertAtCursor('**', '**');\nconst insertItalic = () => insertAtCursor('_', '_');\nconst insertCode = () => insertAtCursor('`', '`');\nconst insertCodeBlock = () => insertAtCursor('\\n```\\n', '\\n```\\n');\nconst insertLink = () => insertAtCursor('[', '](url)');\nconst insertList = () => insertAtCursor('\\n- ');\nconst insertOrderedList = () => insertAtCursor('\\n1. ');\nconst insertQuote = () => insertAtCursor('\\n> ');\nconst insertHr = () => insertAtCursor('\\n---\\n');\n\n/* ──────── Markdown → HTML rendering ──────── */\n\nconst renderedHtml = computed(() => {\n return markdownToHtml(stringValue.value);\n});\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction markdownToHtml(md: string): string {\n if (!md) return '';\n\n const lines = md.split('\\n');\n const html: string[] = [];\n let inCodeBlock = false;\n let inList = false;\n let inOrderedList = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Code blocks\n if (line.trim().startsWith('```')) {\n if (inCodeBlock) {\n html.push('</code></pre>');\n inCodeBlock = false;\n } else {\n inCodeBlock = true;\n html.push('<pre class=\"t-md-editor__code-block\"><code>');\n }\n continue;\n }\n\n if (inCodeBlock) {\n html.push(escapeHtml(line));\n html.push('\\n');\n continue;\n }\n\n // Close open lists if needed\n const isUnorderedListItem = /^[-*+]\\s/.test(line.trim());\n const isOrderedListItem = /^\\d+\\.\\s/.test(line.trim());\n\n if (inList && !isUnorderedListItem) {\n html.push('</ul>');\n inList = false;\n }\n if (inOrderedList && !isOrderedListItem) {\n html.push('</ol>');\n inOrderedList = false;\n }\n\n // Horizontal rule\n if (/^(-{3,}|_{3,}|\\*{3,})$/.test(line.trim())) {\n html.push('<hr class=\"t-md-editor__hr\" />');\n continue;\n }\n\n // Headings\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n const level = headingMatch[1].length;\n html.push(`<h${level} class=\"t-md-editor__heading t-md-editor__heading--${level}\">${inlineMarkdown(escapeHtml(headingMatch[2]))}</h${level}>`);\n continue;\n }\n\n // Blockquote\n if (line.trim().startsWith('> ')) {\n html.push(`<blockquote class=\"t-md-editor__blockquote\">${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</blockquote>`);\n continue;\n }\n\n // Unordered list\n if (isUnorderedListItem) {\n if (!inList) {\n html.push('<ul class=\"t-md-editor__list\">');\n inList = true;\n }\n html.push(`<li>${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</li>`);\n continue;\n }\n\n // Ordered list\n if (isOrderedListItem) {\n if (!inOrderedList) {\n html.push('<ol class=\"t-md-editor__list t-md-editor__list--ordered\">');\n inOrderedList = true;\n }\n const content = line.trim().replace(/^\\d+\\.\\s/, '');\n html.push(`<li>${inlineMarkdown(escapeHtml(content))}</li>`);\n continue;\n }\n\n // Empty line\n if (line.trim() === '') {\n html.push('<br />');\n continue;\n }\n\n // Paragraph\n html.push(`<p class=\"t-md-editor__paragraph\">${inlineMarkdown(escapeHtml(line))}</p>`);\n }\n\n // Close any open blocks\n if (inCodeBlock) html.push('</code></pre>');\n if (inList) html.push('</ul>');\n if (inOrderedList) html.push('</ol>');\n\n return html.join('\\n');\n}\n\nfunction inlineMarkdown(text: string): string {\n // Images: \n text = text.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '<img src=\"$2\" alt=\"$1\" class=\"t-md-editor__image\" loading=\"lazy\" />');\n // Links: [text](url)\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>');\n // Bold: **text**\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n // Italic: _text_ or *text*\n text = text.replace(/_(.+?)_/g, '<em>$1</em>');\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, '<em>$1</em>');\n // Inline code: `text`\n text = text.replace(/`(.+?)`/g, '<code class=\"t-md-editor__inline-code\">$1</code>');\n // Strikethrough: ~~text~~\n text = text.replace(/~~(.+?)~~/g, '<del>$1</del>');\n return text;\n}\n\n/* ──────── Image paste / drop handling ──────── */\n\nconst handlePaste = async (event: ClipboardEvent) => {\n if (props.disabled) return;\n\n const items = event.clipboardData?.items;\n if (!items) return;\n\n for (const item of items) {\n if (item.type.startsWith('image/')) {\n event.preventDefault();\n const file = item.getAsFile();\n if (file) await processImageUpload(file);\n return;\n }\n }\n};\n\nconst handleDrop = async (event: DragEvent) => {\n if (props.disabled) return;\n\n const files = event.dataTransfer?.files;\n if (!files) return;\n\n for (const file of files) {\n if (file.type.startsWith('image/')) {\n event.preventDefault();\n await processImageUpload(file);\n }\n }\n};\n\nconst handleDragOver = (event: DragEvent) => {\n if (props.disabled) return;\n event.preventDefault();\n};\n\nconst processImageUpload = async (file: File) => {\n if (!props.uploadImage) {\n // Fallback: insert a placeholder with the file name\n insertAtCursor(`![${file.name}]()`);\n return;\n }\n\n // Insert uploading placeholder\n const placeholder = `![Uploading ${file.name}...]()`;\n insertAtCursor(placeholder);\n isUploading.value = true;\n\n try {\n const url = props.uploadImage(file);\n const resolvedUrl = url instanceof Promise ? await url : url;\n\n // Replace placeholder with actual URL\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, ``);\n emit('update:modelValue', newValue);\n emit('image-upload', file, resolvedUrl);\n } catch (err) {\n // Remove placeholder on error\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, '');\n emit('update:modelValue', newValue);\n emit('image-upload-error', file, err instanceof Error ? err : new Error(String(err)));\n } finally {\n isUploading.value = false;\n }\n};\n\n/* ──────── Keyboard shortcuts ──────── */\n\nconst handleKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n const mod = event.metaKey || event.ctrlKey;\n if (!mod) return;\n\n switch (event.key) {\n case 'b':\n event.preventDefault();\n insertBold();\n break;\n case 'i':\n event.preventDefault();\n insertItalic();\n break;\n case 'k':\n event.preventDefault();\n insertLink();\n break;\n case 'e':\n event.preventDefault();\n insertCode();\n break;\n }\n};\n\n</script>\n\n<template>\n <div\n v-bind=\"editorAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <!-- Toolbar -->\n <div\n class=\"t-md-editor__toolbar\"\n role=\"toolbar\"\n aria-label=\"Markdown formatting\"\n >\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 1 (H1)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(1)\"\n >\n H1\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 2 (H2)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(2)\"\n >\n H2\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 3 (H3)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(3)\"\n >\n H3\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Bold (Ctrl+B)\"\n :disabled=\"disabled\"\n @click=\"insertBold\"\n >\n <strong>B</strong>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Italic (Ctrl+I)\"\n :disabled=\"disabled\"\n @click=\"insertItalic\"\n >\n <em>I</em>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Strikethrough\"\n :disabled=\"disabled\"\n @click=\"insertAtCursor('~~', '~~')\"\n >\n <del>S</del>\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Inline code (Ctrl+E)\"\n :disabled=\"disabled\"\n @click=\"insertCode\"\n >\n </>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Code block\"\n :disabled=\"disabled\"\n @click=\"insertCodeBlock\"\n >\n { }\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Link (Ctrl+K)\"\n :disabled=\"disabled\"\n @click=\"insertLink\"\n >\n 🔗\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Unordered list\"\n :disabled=\"disabled\"\n @click=\"insertList\"\n >\n • List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Ordered list\"\n :disabled=\"disabled\"\n @click=\"insertOrderedList\"\n >\n 1. List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Blockquote\"\n :disabled=\"disabled\"\n @click=\"insertQuote\"\n >\n >\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Horizontal rule\"\n :disabled=\"disabled\"\n @click=\"insertHr\"\n >\n ―\n </button>\n </div>\n\n <slot name=\"toolbar\" />\n </div>\n\n <!-- Editor body -->\n <div class=\"t-md-editor__body\">\n <!-- Write pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--write\"\n >\n <textarea\n ref=\"textareaRef\"\n class=\"t-md-editor__textarea\"\n :value=\"stringValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-label=\"placeholder\"\n @input=\"onInput\"\n @paste=\"handlePaste\"\n @drop=\"handleDrop\"\n @dragover=\"handleDragOver\"\n @keydown=\"handleKeydown\"\n />\n </div>\n\n <!-- Preview pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--preview\"\n aria-label=\"Markdown preview\"\n >\n <!-- eslint-disable vue/no-v-html -->\n <div\n class=\"t-md-editor__preview\"\n v-html=\"renderedHtml\"\n />\n <!-- eslint-enable vue/no-v-html -->\n </div>\n </div>\n\n <!-- Upload indicator -->\n <div\n v-if=\"isUploading\"\n class=\"t-md-editor__upload-bar\"\n role=\"status\"\n aria-live=\"polite\"\n >\n Uploading image…\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { computed as e, createCommentVNode as t, createElementBlock as n, createElementVNode as r, defineComponent as i, mergeProps as a, nextTick as o, openBlock as s, ref as c, renderSlot as l, useAttrs as u } from "vue";
|
|
2
|
+
//#region src/components/TMarkdownEditor.vue?vue&type=script&setup=true&lang.ts
|
|
3
|
+
var d = {
|
|
4
|
+
class: "t-md-editor__toolbar",
|
|
5
|
+
role: "toolbar",
|
|
6
|
+
"aria-label": "Markdown formatting"
|
|
7
|
+
}, f = { class: "t-md-editor__toolbar-group" }, p = ["disabled"], ee = ["disabled"], m = ["disabled"], te = { class: "t-md-editor__toolbar-group" }, ne = ["disabled"], h = ["disabled"], g = ["disabled"], _ = { class: "t-md-editor__toolbar-group" }, v = ["disabled"], y = ["disabled"], b = ["disabled"], x = { class: "t-md-editor__toolbar-group" }, S = ["disabled"], C = ["disabled"], w = ["disabled"], re = ["disabled"], T = { class: "t-md-editor__body" }, E = { class: "t-md-editor__pane t-md-editor__pane--write" }, D = [
|
|
8
|
+
"value",
|
|
9
|
+
"placeholder",
|
|
10
|
+
"disabled",
|
|
11
|
+
"aria-label"
|
|
12
|
+
], O = {
|
|
13
|
+
class: "t-md-editor__pane t-md-editor__pane--preview",
|
|
14
|
+
"aria-label": "Markdown preview"
|
|
15
|
+
}, k = ["innerHTML"], A = {
|
|
16
|
+
key: 0,
|
|
17
|
+
class: "t-md-editor__upload-bar",
|
|
18
|
+
role: "status",
|
|
19
|
+
"aria-live": "polite"
|
|
20
|
+
}, j = /*@__PURE__*/ i({
|
|
21
|
+
inheritAttrs: !1,
|
|
22
|
+
__name: "TMarkdownEditor",
|
|
23
|
+
props: {
|
|
24
|
+
modelValue: { default: "" },
|
|
25
|
+
size: { default: "md" },
|
|
26
|
+
disabled: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: !1
|
|
29
|
+
},
|
|
30
|
+
placeholder: { default: "Write your markdown here..." },
|
|
31
|
+
uploadImage: {
|
|
32
|
+
type: Function,
|
|
33
|
+
default: void 0
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
emits: [
|
|
37
|
+
"update:modelValue",
|
|
38
|
+
"image-upload",
|
|
39
|
+
"image-upload-error"
|
|
40
|
+
],
|
|
41
|
+
setup(i, { emit: j }) {
|
|
42
|
+
let M = i, N = j, P = u(), F = c(null), I = c(!1), L = e(() => [
|
|
43
|
+
"t-md-editor",
|
|
44
|
+
`t-md-editor--${M.size}`,
|
|
45
|
+
{
|
|
46
|
+
"is-disabled": M.disabled,
|
|
47
|
+
"is-uploading": I.value
|
|
48
|
+
},
|
|
49
|
+
P.class
|
|
50
|
+
]), R = e(() => P.style), z = e(() => {
|
|
51
|
+
let { class: e, style: t, ...n } = P;
|
|
52
|
+
return n;
|
|
53
|
+
}), B = e(() => `${M.modelValue ?? ""}`), V = (e) => {
|
|
54
|
+
N("update:modelValue", e.target.value);
|
|
55
|
+
}, H = (e, t = "") => {
|
|
56
|
+
let n = F.value;
|
|
57
|
+
if (!n) return;
|
|
58
|
+
let r = n.selectionStart, i = n.selectionEnd, a = B.value, s = a.slice(r, i), c = a.slice(0, r) + e + s + t + a.slice(i);
|
|
59
|
+
N("update:modelValue", c), o(() => {
|
|
60
|
+
n.focus();
|
|
61
|
+
let i = s ? r + e.length + s.length + t.length : r + e.length;
|
|
62
|
+
n.setSelectionRange(i, i);
|
|
63
|
+
});
|
|
64
|
+
}, U = (e) => {
|
|
65
|
+
let t = "#".repeat(e) + " ", n = F.value;
|
|
66
|
+
if (!n) return;
|
|
67
|
+
let r = n.selectionStart, i = B.value, a = i.lastIndexOf("\n", r - 1) + 1, s = i.indexOf("\n", r), c = s === -1 ? i.length : s, l = t + i.slice(a, c).replace(/^#{1,6}\s*/, ""), u = i.slice(0, a) + l + i.slice(c);
|
|
68
|
+
N("update:modelValue", u), o(() => {
|
|
69
|
+
n.focus(), n.setSelectionRange(a + l.length, a + l.length);
|
|
70
|
+
});
|
|
71
|
+
}, W = () => H("**", "**"), G = () => H("_", "_"), K = () => H("`", "`"), q = () => H("\n```\n", "\n```\n"), J = () => H("[", "](url)"), Y = () => H("\n- "), X = () => H("\n1. "), ie = () => H("\n> "), ae = () => H("\n---\n"), oe = e(() => se(B.value));
|
|
72
|
+
function Z(e) {
|
|
73
|
+
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
74
|
+
}
|
|
75
|
+
function se(e) {
|
|
76
|
+
if (!e) return "";
|
|
77
|
+
let t = e.split("\n"), n = [], r = !1, i = !1, a = !1;
|
|
78
|
+
for (let e = 0; e < t.length; e++) {
|
|
79
|
+
let o = t[e];
|
|
80
|
+
if (o.trim().startsWith("```")) {
|
|
81
|
+
r ? (n.push("</code></pre>"), r = !1) : (r = !0, n.push("<pre class=\"t-md-editor__code-block\"><code>"));
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (r) {
|
|
85
|
+
n.push(Z(o)), n.push("\n");
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
let s = /^[-*+]\s/.test(o.trim()), c = /^\d+\.\s/.test(o.trim());
|
|
89
|
+
if (i && !s && (n.push("</ul>"), i = !1), a && !c && (n.push("</ol>"), a = !1), /^(-{3,}|_{3,}|\*{3,})$/.test(o.trim())) {
|
|
90
|
+
n.push("<hr class=\"t-md-editor__hr\" />");
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
let l = o.match(/^(#{1,6})\s+(.+)$/);
|
|
94
|
+
if (l) {
|
|
95
|
+
let e = l[1].length;
|
|
96
|
+
n.push(`<h${e} class="t-md-editor__heading t-md-editor__heading--${e}">${Q(Z(l[2]))}</h${e}>`);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (o.trim().startsWith("> ")) {
|
|
100
|
+
n.push(`<blockquote class="t-md-editor__blockquote">${Q(Z(o.trim().slice(2)))}</blockquote>`);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (s) {
|
|
104
|
+
i ||= (n.push("<ul class=\"t-md-editor__list\">"), !0), n.push(`<li>${Q(Z(o.trim().slice(2)))}</li>`);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (c) {
|
|
108
|
+
a ||= (n.push("<ol class=\"t-md-editor__list t-md-editor__list--ordered\">"), !0);
|
|
109
|
+
let e = o.trim().replace(/^\d+\.\s/, "");
|
|
110
|
+
n.push(`<li>${Q(Z(e))}</li>`);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (o.trim() === "") {
|
|
114
|
+
n.push("<br />");
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
n.push(`<p class="t-md-editor__paragraph">${Q(Z(o))}</p>`);
|
|
118
|
+
}
|
|
119
|
+
return r && n.push("</code></pre>"), i && n.push("</ul>"), a && n.push("</ol>"), n.join("\n");
|
|
120
|
+
}
|
|
121
|
+
function Q(e) {
|
|
122
|
+
return e = e.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, "<img src=\"$2\" alt=\"$1\" class=\"t-md-editor__image\" loading=\"lazy\" />"), e = e.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>"), e = e.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>"), e = e.replace(/_(.+?)_/g, "<em>$1</em>"), e = e.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g, "<em>$1</em>"), e = e.replace(/`(.+?)`/g, "<code class=\"t-md-editor__inline-code\">$1</code>"), e = e.replace(/~~(.+?)~~/g, "<del>$1</del>"), e;
|
|
123
|
+
}
|
|
124
|
+
let ce = async (e) => {
|
|
125
|
+
if (M.disabled) return;
|
|
126
|
+
let t = e.clipboardData?.items;
|
|
127
|
+
if (t) {
|
|
128
|
+
for (let n of t) if (n.type.startsWith("image/")) {
|
|
129
|
+
e.preventDefault();
|
|
130
|
+
let t = n.getAsFile();
|
|
131
|
+
t && await $(t);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}, le = async (e) => {
|
|
136
|
+
if (M.disabled) return;
|
|
137
|
+
let t = e.dataTransfer?.files;
|
|
138
|
+
if (t) for (let n of t) n.type.startsWith("image/") && (e.preventDefault(), await $(n));
|
|
139
|
+
}, ue = (e) => {
|
|
140
|
+
M.disabled || e.preventDefault();
|
|
141
|
+
}, $ = async (e) => {
|
|
142
|
+
if (!M.uploadImage) {
|
|
143
|
+
H(`![${e.name}]()`);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
let t = `![Uploading ${e.name}...]()`;
|
|
147
|
+
H(t), I.value = !0;
|
|
148
|
+
try {
|
|
149
|
+
let n = M.uploadImage(e), r = n instanceof Promise ? await n : n, i = B.value.replace(t, ``);
|
|
150
|
+
N("update:modelValue", i), N("image-upload", e, r);
|
|
151
|
+
} catch (n) {
|
|
152
|
+
let r = B.value.replace(t, "");
|
|
153
|
+
N("update:modelValue", r), N("image-upload-error", e, n instanceof Error ? n : Error(String(n)));
|
|
154
|
+
} finally {
|
|
155
|
+
I.value = !1;
|
|
156
|
+
}
|
|
157
|
+
}, de = (e) => {
|
|
158
|
+
if (!M.disabled && (e.metaKey || e.ctrlKey)) switch (e.key) {
|
|
159
|
+
case "b":
|
|
160
|
+
e.preventDefault(), W();
|
|
161
|
+
break;
|
|
162
|
+
case "i":
|
|
163
|
+
e.preventDefault(), G();
|
|
164
|
+
break;
|
|
165
|
+
case "k":
|
|
166
|
+
e.preventDefault(), J();
|
|
167
|
+
break;
|
|
168
|
+
case "e":
|
|
169
|
+
e.preventDefault(), K();
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
return (e, o) => (s(), n("div", a(z.value, {
|
|
174
|
+
class: L.value,
|
|
175
|
+
style: R.value
|
|
176
|
+
}), [
|
|
177
|
+
r("div", d, [
|
|
178
|
+
r("div", f, [
|
|
179
|
+
r("button", {
|
|
180
|
+
type: "button",
|
|
181
|
+
class: "t-md-editor__toolbar-btn",
|
|
182
|
+
title: "Heading 1 (H1)",
|
|
183
|
+
disabled: i.disabled,
|
|
184
|
+
onClick: o[0] ||= (e) => U(1)
|
|
185
|
+
}, " H1 ", 8, p),
|
|
186
|
+
r("button", {
|
|
187
|
+
type: "button",
|
|
188
|
+
class: "t-md-editor__toolbar-btn",
|
|
189
|
+
title: "Heading 2 (H2)",
|
|
190
|
+
disabled: i.disabled,
|
|
191
|
+
onClick: o[1] ||= (e) => U(2)
|
|
192
|
+
}, " H2 ", 8, ee),
|
|
193
|
+
r("button", {
|
|
194
|
+
type: "button",
|
|
195
|
+
class: "t-md-editor__toolbar-btn",
|
|
196
|
+
title: "Heading 3 (H3)",
|
|
197
|
+
disabled: i.disabled,
|
|
198
|
+
onClick: o[2] ||= (e) => U(3)
|
|
199
|
+
}, " H3 ", 8, m)
|
|
200
|
+
]),
|
|
201
|
+
o[7] ||= r("div", {
|
|
202
|
+
class: "t-md-editor__toolbar-divider",
|
|
203
|
+
role: "separator"
|
|
204
|
+
}, null, -1),
|
|
205
|
+
r("div", te, [
|
|
206
|
+
r("button", {
|
|
207
|
+
type: "button",
|
|
208
|
+
class: "t-md-editor__toolbar-btn",
|
|
209
|
+
title: "Bold (Ctrl+B)",
|
|
210
|
+
disabled: i.disabled,
|
|
211
|
+
onClick: W
|
|
212
|
+
}, [...o[4] ||= [r("strong", null, "B", -1)]], 8, ne),
|
|
213
|
+
r("button", {
|
|
214
|
+
type: "button",
|
|
215
|
+
class: "t-md-editor__toolbar-btn",
|
|
216
|
+
title: "Italic (Ctrl+I)",
|
|
217
|
+
disabled: i.disabled,
|
|
218
|
+
onClick: G
|
|
219
|
+
}, [...o[5] ||= [r("em", null, "I", -1)]], 8, h),
|
|
220
|
+
r("button", {
|
|
221
|
+
type: "button",
|
|
222
|
+
class: "t-md-editor__toolbar-btn",
|
|
223
|
+
title: "Strikethrough",
|
|
224
|
+
disabled: i.disabled,
|
|
225
|
+
onClick: o[3] ||= (e) => H("~~", "~~")
|
|
226
|
+
}, [...o[6] ||= [r("del", null, "S", -1)]], 8, g)
|
|
227
|
+
]),
|
|
228
|
+
o[8] ||= r("div", {
|
|
229
|
+
class: "t-md-editor__toolbar-divider",
|
|
230
|
+
role: "separator"
|
|
231
|
+
}, null, -1),
|
|
232
|
+
r("div", _, [
|
|
233
|
+
r("button", {
|
|
234
|
+
type: "button",
|
|
235
|
+
class: "t-md-editor__toolbar-btn",
|
|
236
|
+
title: "Inline code (Ctrl+E)",
|
|
237
|
+
disabled: i.disabled,
|
|
238
|
+
onClick: K
|
|
239
|
+
}, " </> ", 8, v),
|
|
240
|
+
r("button", {
|
|
241
|
+
type: "button",
|
|
242
|
+
class: "t-md-editor__toolbar-btn",
|
|
243
|
+
title: "Code block",
|
|
244
|
+
disabled: i.disabled,
|
|
245
|
+
onClick: q
|
|
246
|
+
}, " { } ", 8, y),
|
|
247
|
+
r("button", {
|
|
248
|
+
type: "button",
|
|
249
|
+
class: "t-md-editor__toolbar-btn",
|
|
250
|
+
title: "Link (Ctrl+K)",
|
|
251
|
+
disabled: i.disabled,
|
|
252
|
+
onClick: J
|
|
253
|
+
}, " 🔗 ", 8, b)
|
|
254
|
+
]),
|
|
255
|
+
o[9] ||= r("div", {
|
|
256
|
+
class: "t-md-editor__toolbar-divider",
|
|
257
|
+
role: "separator"
|
|
258
|
+
}, null, -1),
|
|
259
|
+
r("div", x, [
|
|
260
|
+
r("button", {
|
|
261
|
+
type: "button",
|
|
262
|
+
class: "t-md-editor__toolbar-btn",
|
|
263
|
+
title: "Unordered list",
|
|
264
|
+
disabled: i.disabled,
|
|
265
|
+
onClick: Y
|
|
266
|
+
}, " •\xA0List ", 8, S),
|
|
267
|
+
r("button", {
|
|
268
|
+
type: "button",
|
|
269
|
+
class: "t-md-editor__toolbar-btn",
|
|
270
|
+
title: "Ordered list",
|
|
271
|
+
disabled: i.disabled,
|
|
272
|
+
onClick: X
|
|
273
|
+
}, " 1.\xA0List ", 8, C),
|
|
274
|
+
r("button", {
|
|
275
|
+
type: "button",
|
|
276
|
+
class: "t-md-editor__toolbar-btn",
|
|
277
|
+
title: "Blockquote",
|
|
278
|
+
disabled: i.disabled,
|
|
279
|
+
onClick: ie
|
|
280
|
+
}, " > ", 8, w),
|
|
281
|
+
r("button", {
|
|
282
|
+
type: "button",
|
|
283
|
+
class: "t-md-editor__toolbar-btn",
|
|
284
|
+
title: "Horizontal rule",
|
|
285
|
+
disabled: i.disabled,
|
|
286
|
+
onClick: ae
|
|
287
|
+
}, " ― ", 8, re)
|
|
288
|
+
]),
|
|
289
|
+
l(e.$slots, "toolbar")
|
|
290
|
+
]),
|
|
291
|
+
r("div", T, [r("div", E, [r("textarea", {
|
|
292
|
+
ref_key: "textareaRef",
|
|
293
|
+
ref: F,
|
|
294
|
+
class: "t-md-editor__textarea",
|
|
295
|
+
value: B.value,
|
|
296
|
+
placeholder: i.placeholder,
|
|
297
|
+
disabled: i.disabled,
|
|
298
|
+
"aria-label": i.placeholder,
|
|
299
|
+
onInput: V,
|
|
300
|
+
onPaste: ce,
|
|
301
|
+
onDrop: le,
|
|
302
|
+
onDragover: ue,
|
|
303
|
+
onKeydown: de
|
|
304
|
+
}, null, 40, D)]), r("div", O, [r("div", {
|
|
305
|
+
class: "t-md-editor__preview",
|
|
306
|
+
innerHTML: oe.value
|
|
307
|
+
}, null, 8, k)])]),
|
|
308
|
+
I.value ? (s(), n("div", A, " Uploading image… ")) : t("", !0)
|
|
309
|
+
], 16));
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
//#endregion
|
|
313
|
+
export { j as default };
|
|
314
|
+
|
|
315
|
+
//# sourceMappingURL=TMarkdownEditor.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TMarkdownEditor.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../src/components/TMarkdownEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, nextTick } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n size?: TSize;\n disabled?: boolean;\n placeholder?: string;\n uploadImage?: (file: File) => Promise<string>;\n }>(),\n {\n modelValue: '',\n size: 'md',\n disabled: false,\n placeholder: 'Write your markdown here...',\n uploadImage: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'image-upload': [file: File, url: string];\n 'image-upload-error': [file: File, error: Error];\n}>();\n\ndefineSlots<{\n toolbar?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst textareaRef = ref<HTMLTextAreaElement | null>(null);\nconst isUploading = ref(false);\n\nconst rootClasses = computed(() => [\n 't-md-editor',\n `t-md-editor--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-uploading': isUploading.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst editorAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst stringValue = computed(() => `${props.modelValue ?? ''}`);\n\nconst onInput = (event: Event) => {\n emit('update:modelValue', (event.target as HTMLTextAreaElement).value);\n};\n\n/* ──────── Toolbar Actions ──────── */\n\nconst insertAtCursor = (before: string, after = '') => {\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const end = el.selectionEnd;\n const text = stringValue.value;\n const selected = text.slice(start, end);\n\n const newText = text.slice(0, start) + before + selected + after + text.slice(end);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n const cursorPos = selected\n ? start + before.length + selected.length + after.length\n : start + before.length;\n el.setSelectionRange(cursorPos, cursorPos);\n });\n};\n\nconst insertHeading = (level: number) => {\n const prefix = '#'.repeat(level) + ' ';\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const text = stringValue.value;\n\n // Find start of current line\n const lineStart = text.lastIndexOf('\\n', start - 1) + 1;\n const lineEnd = text.indexOf('\\n', start);\n const actualEnd = lineEnd === -1 ? text.length : lineEnd;\n const line = text.slice(lineStart, actualEnd);\n\n // Strip existing heading markers\n const stripped = line.replace(/^#{1,6}\\s*/, '');\n const newLine = prefix + stripped;\n\n const newText = text.slice(0, lineStart) + newLine + text.slice(actualEnd);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n el.setSelectionRange(lineStart + newLine.length, lineStart + newLine.length);\n });\n};\n\nconst insertBold = () => insertAtCursor('**', '**');\nconst insertItalic = () => insertAtCursor('_', '_');\nconst insertCode = () => insertAtCursor('`', '`');\nconst insertCodeBlock = () => insertAtCursor('\\n```\\n', '\\n```\\n');\nconst insertLink = () => insertAtCursor('[', '](url)');\nconst insertList = () => insertAtCursor('\\n- ');\nconst insertOrderedList = () => insertAtCursor('\\n1. ');\nconst insertQuote = () => insertAtCursor('\\n> ');\nconst insertHr = () => insertAtCursor('\\n---\\n');\n\n/* ──────── Markdown → HTML rendering ──────── */\n\nconst renderedHtml = computed(() => {\n return markdownToHtml(stringValue.value);\n});\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction markdownToHtml(md: string): string {\n if (!md) return '';\n\n const lines = md.split('\\n');\n const html: string[] = [];\n let inCodeBlock = false;\n let inList = false;\n let inOrderedList = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Code blocks\n if (line.trim().startsWith('```')) {\n if (inCodeBlock) {\n html.push('</code></pre>');\n inCodeBlock = false;\n } else {\n inCodeBlock = true;\n html.push('<pre class=\"t-md-editor__code-block\"><code>');\n }\n continue;\n }\n\n if (inCodeBlock) {\n html.push(escapeHtml(line));\n html.push('\\n');\n continue;\n }\n\n // Close open lists if needed\n const isUnorderedListItem = /^[-*+]\\s/.test(line.trim());\n const isOrderedListItem = /^\\d+\\.\\s/.test(line.trim());\n\n if (inList && !isUnorderedListItem) {\n html.push('</ul>');\n inList = false;\n }\n if (inOrderedList && !isOrderedListItem) {\n html.push('</ol>');\n inOrderedList = false;\n }\n\n // Horizontal rule\n if (/^(-{3,}|_{3,}|\\*{3,})$/.test(line.trim())) {\n html.push('<hr class=\"t-md-editor__hr\" />');\n continue;\n }\n\n // Headings\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n const level = headingMatch[1].length;\n html.push(`<h${level} class=\"t-md-editor__heading t-md-editor__heading--${level}\">${inlineMarkdown(escapeHtml(headingMatch[2]))}</h${level}>`);\n continue;\n }\n\n // Blockquote\n if (line.trim().startsWith('> ')) {\n html.push(`<blockquote class=\"t-md-editor__blockquote\">${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</blockquote>`);\n continue;\n }\n\n // Unordered list\n if (isUnorderedListItem) {\n if (!inList) {\n html.push('<ul class=\"t-md-editor__list\">');\n inList = true;\n }\n html.push(`<li>${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</li>`);\n continue;\n }\n\n // Ordered list\n if (isOrderedListItem) {\n if (!inOrderedList) {\n html.push('<ol class=\"t-md-editor__list t-md-editor__list--ordered\">');\n inOrderedList = true;\n }\n const content = line.trim().replace(/^\\d+\\.\\s/, '');\n html.push(`<li>${inlineMarkdown(escapeHtml(content))}</li>`);\n continue;\n }\n\n // Empty line\n if (line.trim() === '') {\n html.push('<br />');\n continue;\n }\n\n // Paragraph\n html.push(`<p class=\"t-md-editor__paragraph\">${inlineMarkdown(escapeHtml(line))}</p>`);\n }\n\n // Close any open blocks\n if (inCodeBlock) html.push('</code></pre>');\n if (inList) html.push('</ul>');\n if (inOrderedList) html.push('</ol>');\n\n return html.join('\\n');\n}\n\nfunction inlineMarkdown(text: string): string {\n // Images: \n text = text.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '<img src=\"$2\" alt=\"$1\" class=\"t-md-editor__image\" loading=\"lazy\" />');\n // Links: [text](url)\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>');\n // Bold: **text**\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n // Italic: _text_ or *text*\n text = text.replace(/_(.+?)_/g, '<em>$1</em>');\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, '<em>$1</em>');\n // Inline code: `text`\n text = text.replace(/`(.+?)`/g, '<code class=\"t-md-editor__inline-code\">$1</code>');\n // Strikethrough: ~~text~~\n text = text.replace(/~~(.+?)~~/g, '<del>$1</del>');\n return text;\n}\n\n/* ──────── Image paste / drop handling ──────── */\n\nconst handlePaste = async (event: ClipboardEvent) => {\n if (props.disabled) return;\n\n const items = event.clipboardData?.items;\n if (!items) return;\n\n for (const item of items) {\n if (item.type.startsWith('image/')) {\n event.preventDefault();\n const file = item.getAsFile();\n if (file) await processImageUpload(file);\n return;\n }\n }\n};\n\nconst handleDrop = async (event: DragEvent) => {\n if (props.disabled) return;\n\n const files = event.dataTransfer?.files;\n if (!files) return;\n\n for (const file of files) {\n if (file.type.startsWith('image/')) {\n event.preventDefault();\n await processImageUpload(file);\n }\n }\n};\n\nconst handleDragOver = (event: DragEvent) => {\n if (props.disabled) return;\n event.preventDefault();\n};\n\nconst processImageUpload = async (file: File) => {\n if (!props.uploadImage) {\n // Fallback: insert a placeholder with the file name\n insertAtCursor(`![${file.name}]()`);\n return;\n }\n\n // Insert uploading placeholder\n const placeholder = `![Uploading ${file.name}...]()`;\n insertAtCursor(placeholder);\n isUploading.value = true;\n\n try {\n const url = props.uploadImage(file);\n const resolvedUrl = url instanceof Promise ? await url : url;\n\n // Replace placeholder with actual URL\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, ``);\n emit('update:modelValue', newValue);\n emit('image-upload', file, resolvedUrl);\n } catch (err) {\n // Remove placeholder on error\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, '');\n emit('update:modelValue', newValue);\n emit('image-upload-error', file, err instanceof Error ? err : new Error(String(err)));\n } finally {\n isUploading.value = false;\n }\n};\n\n/* ──────── Keyboard shortcuts ──────── */\n\nconst handleKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n const mod = event.metaKey || event.ctrlKey;\n if (!mod) return;\n\n switch (event.key) {\n case 'b':\n event.preventDefault();\n insertBold();\n break;\n case 'i':\n event.preventDefault();\n insertItalic();\n break;\n case 'k':\n event.preventDefault();\n insertLink();\n break;\n case 'e':\n event.preventDefault();\n insertCode();\n break;\n }\n};\n\n</script>\n\n<template>\n <div\n v-bind=\"editorAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <!-- Toolbar -->\n <div\n class=\"t-md-editor__toolbar\"\n role=\"toolbar\"\n aria-label=\"Markdown formatting\"\n >\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 1 (H1)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(1)\"\n >\n H1\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 2 (H2)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(2)\"\n >\n H2\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 3 (H3)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(3)\"\n >\n H3\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Bold (Ctrl+B)\"\n :disabled=\"disabled\"\n @click=\"insertBold\"\n >\n <strong>B</strong>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Italic (Ctrl+I)\"\n :disabled=\"disabled\"\n @click=\"insertItalic\"\n >\n <em>I</em>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Strikethrough\"\n :disabled=\"disabled\"\n @click=\"insertAtCursor('~~', '~~')\"\n >\n <del>S</del>\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Inline code (Ctrl+E)\"\n :disabled=\"disabled\"\n @click=\"insertCode\"\n >\n </>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Code block\"\n :disabled=\"disabled\"\n @click=\"insertCodeBlock\"\n >\n { }\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Link (Ctrl+K)\"\n :disabled=\"disabled\"\n @click=\"insertLink\"\n >\n 🔗\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Unordered list\"\n :disabled=\"disabled\"\n @click=\"insertList\"\n >\n • List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Ordered list\"\n :disabled=\"disabled\"\n @click=\"insertOrderedList\"\n >\n 1. List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Blockquote\"\n :disabled=\"disabled\"\n @click=\"insertQuote\"\n >\n >\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Horizontal rule\"\n :disabled=\"disabled\"\n @click=\"insertHr\"\n >\n ―\n </button>\n </div>\n\n <slot name=\"toolbar\" />\n </div>\n\n <!-- Editor body -->\n <div class=\"t-md-editor__body\">\n <!-- Write pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--write\"\n >\n <textarea\n ref=\"textareaRef\"\n class=\"t-md-editor__textarea\"\n :value=\"stringValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-label=\"placeholder\"\n @input=\"onInput\"\n @paste=\"handlePaste\"\n @drop=\"handleDrop\"\n @dragover=\"handleDragOver\"\n @keydown=\"handleKeydown\"\n />\n </div>\n\n <!-- Preview pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--preview\"\n aria-label=\"Markdown preview\"\n >\n <!-- eslint-disable vue/no-v-html -->\n <div\n class=\"t-md-editor__preview\"\n v-html=\"renderedHtml\"\n />\n <!-- eslint-enable vue/no-v-html -->\n </div>\n </div>\n\n <!-- Upload indicator -->\n <div\n v-if=\"isUploading\"\n class=\"t-md-editor__upload-bar\"\n role=\"status\"\n aria-live=\"polite\"\n >\n Uploading image…\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|