@betterstart/cli 0.1.2 → 0.1.4
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 +133 -0
- package/dist/cli.d.ts +1 -9
- package/dist/cli.js +13484 -354
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +24 -260
- package/dist/index.js +4 -11373
- package/dist/index.js.map +1 -1
- package/package.json +29 -42
- package/templates/schema.json +959 -0
- package/templates/tiptap/hooks/use-composed-ref.ts +43 -0
- package/templates/tiptap/hooks/use-cursor-visibility.ts +68 -0
- package/templates/tiptap/hooks/use-element-rect.ts +166 -0
- package/templates/tiptap/hooks/use-is-breakpoint.ts +32 -0
- package/templates/tiptap/hooks/use-menu-navigation.ts +182 -0
- package/templates/tiptap/hooks/use-scrolling.ts +64 -0
- package/templates/tiptap/hooks/use-throttled-callback.ts +146 -0
- package/templates/tiptap/hooks/use-tiptap-editor.ts +46 -0
- package/templates/tiptap/hooks/use-unmount.ts +21 -0
- package/templates/tiptap/hooks/use-window-size.ts +87 -0
- package/templates/tiptap/lib/tiptap-utils.ts +587 -0
- package/templates/tiptap/styles/_keyframe-animations.scss +91 -0
- package/templates/tiptap/styles/_variables.scss +296 -0
- package/templates/tiptap/tiptap-extension/node-background-extension.ts +138 -0
- package/templates/tiptap/tiptap-icons/align-center-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/align-justify-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/align-left-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/align-right-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/arrow-left-icon.tsx +24 -0
- package/templates/tiptap/tiptap-icons/ban-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/blockquote-icon.tsx +44 -0
- package/templates/tiptap/tiptap-icons/bold-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/chevron-down-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/close-icon.tsx +24 -0
- package/templates/tiptap/tiptap-icons/code-block-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/code2-icon.tsx +32 -0
- package/templates/tiptap/tiptap-icons/corner-down-left-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/external-link-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/heading-five-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/heading-four-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/heading-icon.tsx +24 -0
- package/templates/tiptap/tiptap-icons/heading-one-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/heading-six-icon.tsx +30 -0
- package/templates/tiptap/tiptap-icons/heading-three-icon.tsx +36 -0
- package/templates/tiptap/tiptap-icons/heading-two-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/highlighter-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/image-plus-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/italic-icon.tsx +24 -0
- package/templates/tiptap/tiptap-icons/link-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/list-icon.tsx +56 -0
- package/templates/tiptap/tiptap-icons/list-ordered-icon.tsx +56 -0
- package/templates/tiptap/tiptap-icons/list-todo-icon.tsx +50 -0
- package/templates/tiptap/tiptap-icons/moon-star-icon.tsx +30 -0
- package/templates/tiptap/tiptap-icons/redo2-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/strike-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/subscript-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/sun-icon.tsx +58 -0
- package/templates/tiptap/tiptap-icons/superscript-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/trash-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/underline-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/undo2-icon.tsx +26 -0
- package/templates/tiptap/tiptap-node/blockquote-node/blockquote-node.scss +37 -0
- package/templates/tiptap/tiptap-node/code-block-node/code-block-node.scss +54 -0
- package/templates/tiptap/tiptap-node/heading-node/heading-node.scss +45 -0
- package/templates/tiptap/tiptap-node/horizontal-rule-node/horizontal-rule-node-extension.ts +10 -0
- package/templates/tiptap/tiptap-node/horizontal-rule-node/horizontal-rule-node.scss +25 -0
- package/templates/tiptap/tiptap-node/image-node/image-node.scss +35 -0
- package/templates/tiptap/tiptap-node/image-upload-node/image-upload-node-extension.ts +154 -0
- package/templates/tiptap/tiptap-node/image-upload-node/image-upload-node.scss +249 -0
- package/templates/tiptap/tiptap-node/image-upload-node/image-upload-node.tsx +522 -0
- package/templates/tiptap/tiptap-node/image-upload-node/index.tsx +1 -0
- package/templates/tiptap/tiptap-node/list-node/list-node.scss +208 -0
- package/templates/tiptap/tiptap-node/paragraph-node/paragraph-node.scss +273 -0
- package/templates/tiptap/tiptap-ui/blockquote-button/blockquote-button.tsx +104 -0
- package/templates/tiptap/tiptap-ui/blockquote-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/blockquote-button/use-blockquote.ts +252 -0
- package/templates/tiptap/tiptap-ui/code-block-button/code-block-button.tsx +106 -0
- package/templates/tiptap/tiptap-ui/code-block-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/code-block-button/use-code-block.ts +261 -0
- package/templates/tiptap/tiptap-ui/color-highlight-button/color-highlight-button.scss +49 -0
- package/templates/tiptap/tiptap-ui/color-highlight-button/color-highlight-button.tsx +153 -0
- package/templates/tiptap/tiptap-ui/color-highlight-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/color-highlight-button/use-color-highlight.ts +345 -0
- package/templates/tiptap/tiptap-ui/color-highlight-popover/color-highlight-popover.tsx +207 -0
- package/templates/tiptap/tiptap-ui/color-highlight-popover/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui/heading-button/heading-button.tsx +107 -0
- package/templates/tiptap/tiptap-ui/heading-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/heading-button/use-heading.ts +314 -0
- package/templates/tiptap/tiptap-ui/heading-dropdown-menu/heading-dropdown-menu.tsx +131 -0
- package/templates/tiptap/tiptap-ui/heading-dropdown-menu/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/heading-dropdown-menu/use-heading-dropdown-menu.ts +130 -0
- package/templates/tiptap/tiptap-ui/image-upload-button/image-upload-button.tsx +114 -0
- package/templates/tiptap/tiptap-ui/image-upload-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/image-upload-button/use-image-upload.ts +192 -0
- package/templates/tiptap/tiptap-ui/link-popover/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/link-popover/link-popover.tsx +285 -0
- package/templates/tiptap/tiptap-ui/link-popover/use-link-popover.ts +286 -0
- package/templates/tiptap/tiptap-ui/list-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/list-button/list-button.tsx +108 -0
- package/templates/tiptap/tiptap-ui/list-button/use-list.ts +329 -0
- package/templates/tiptap/tiptap-ui/list-dropdown-menu/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui/list-dropdown-menu/list-dropdown-menu.tsx +123 -0
- package/templates/tiptap/tiptap-ui/list-dropdown-menu/use-list-dropdown-menu.ts +203 -0
- package/templates/tiptap/tiptap-ui/mark-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/mark-button/mark-button.tsx +107 -0
- package/templates/tiptap/tiptap-ui/mark-button/use-mark.ts +206 -0
- package/templates/tiptap/tiptap-ui/text-align-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/text-align-button/text-align-button.tsx +118 -0
- package/templates/tiptap/tiptap-ui/text-align-button/use-text-align.ts +212 -0
- package/templates/tiptap/tiptap-ui/undo-redo-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/undo-redo-button/undo-redo-button.tsx +105 -0
- package/templates/tiptap/tiptap-ui/undo-redo-button/use-undo-redo.ts +173 -0
- package/templates/tiptap/tiptap-ui-primitive/badge/badge-colors.scss +395 -0
- package/templates/tiptap/tiptap-ui-primitive/badge/badge-group.scss +16 -0
- package/templates/tiptap/tiptap-ui-primitive/badge/badge.scss +99 -0
- package/templates/tiptap/tiptap-ui-primitive/badge/badge.tsx +46 -0
- package/templates/tiptap/tiptap-ui-primitive/badge/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/button/button-colors.scss +429 -0
- package/templates/tiptap/tiptap-ui-primitive/button/button-group.scss +22 -0
- package/templates/tiptap/tiptap-ui-primitive/button/button.scss +314 -0
- package/templates/tiptap/tiptap-ui-primitive/button/button.tsx +102 -0
- package/templates/tiptap/tiptap-ui-primitive/button/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/card/card.scss +77 -0
- package/templates/tiptap/tiptap-ui-primitive/card/card.tsx +59 -0
- package/templates/tiptap/tiptap-ui-primitive/card/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/dropdown-menu/dropdown-menu.scss +63 -0
- package/templates/tiptap/tiptap-ui-primitive/dropdown-menu/dropdown-menu.tsx +95 -0
- package/templates/tiptap/tiptap-ui-primitive/dropdown-menu/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/input/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/input/input.scss +45 -0
- package/templates/tiptap/tiptap-ui-primitive/input/input.tsx +18 -0
- package/templates/tiptap/tiptap-ui-primitive/popover/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/popover/popover.scss +63 -0
- package/templates/tiptap/tiptap-ui-primitive/popover/popover.tsx +33 -0
- package/templates/tiptap/tiptap-ui-primitive/separator/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/separator/separator.scss +23 -0
- package/templates/tiptap/tiptap-ui-primitive/separator/separator.tsx +33 -0
- package/templates/tiptap/tiptap-ui-primitive/spacer/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/spacer/spacer.tsx +21 -0
- package/templates/tiptap/tiptap-ui-primitive/toolbar/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/toolbar/toolbar.scss +98 -0
- package/templates/tiptap/tiptap-ui-primitive/toolbar/toolbar.tsx +113 -0
- package/templates/tiptap/tiptap-ui-primitive/tooltip/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/tooltip/tooltip.scss +43 -0
- package/templates/tiptap/tiptap-ui-primitive/tooltip/tooltip.tsx +223 -0
- package/templates/ui/accordion.tsx +52 -0
- package/templates/ui/alert-dialog.tsx +116 -0
- package/templates/ui/alert.tsx +48 -0
- package/templates/ui/aspect-ratio.tsx +7 -0
- package/templates/ui/avatar.tsx +46 -0
- package/templates/ui/badge.tsx +32 -0
- package/templates/ui/breadcrumb.tsx +98 -0
- package/templates/ui/button-group.tsx +77 -0
- package/templates/ui/button.tsx +48 -0
- package/templates/ui/calendar.tsx +176 -0
- package/templates/ui/card.tsx +54 -0
- package/templates/ui/carousel.tsx +234 -0
- package/templates/ui/chart.tsx +349 -0
- package/templates/ui/checkbox.tsx +27 -0
- package/templates/ui/collapsible.tsx +11 -0
- package/templates/ui/command.tsx +142 -0
- package/templates/ui/context-menu.tsx +188 -0
- package/templates/ui/curriculum-editor.tsx +601 -0
- package/templates/ui/date-picker.tsx +70 -0
- package/templates/ui/dialog.tsx +103 -0
- package/templates/ui/drawer.tsx +99 -0
- package/templates/ui/dropdown-menu.tsx +185 -0
- package/templates/ui/dynamic-list-field.tsx +95 -0
- package/templates/ui/empty.tsx +90 -0
- package/templates/ui/field.tsx +231 -0
- package/templates/ui/file-upload-example.tsx +113 -0
- package/templates/ui/form.tsx +172 -0
- package/templates/ui/hover-card.tsx +28 -0
- package/templates/ui/icon-picker.tsx +435 -0
- package/templates/ui/icons-data.ts +6 -0
- package/templates/ui/image-upload-field.tsx +360 -0
- package/templates/ui/input-group.tsx +160 -0
- package/templates/ui/input-otp.tsx +70 -0
- package/templates/ui/input.tsx +21 -0
- package/templates/ui/item.tsx +171 -0
- package/templates/ui/kbd.tsx +28 -0
- package/templates/ui/label.tsx +20 -0
- package/templates/ui/logo.tsx +113 -0
- package/templates/ui/markdown-editor.tsx +303 -0
- package/templates/ui/markdown-utils.ts +128 -0
- package/templates/ui/media-upload-field.tsx +255 -0
- package/templates/ui/menubar.tsx +230 -0
- package/templates/ui/navigation-menu.tsx +119 -0
- package/templates/ui/pagination.tsx +96 -0
- package/templates/ui/placeholder.tsx +25 -0
- package/templates/ui/popover.tsx +32 -0
- package/templates/ui/progress.tsx +24 -0
- package/templates/ui/radio-group.tsx +37 -0
- package/templates/ui/resizable.tsx +41 -0
- package/templates/ui/rich-text-editor.tsx +374 -0
- package/templates/ui/scroll-area.tsx +45 -0
- package/templates/ui/select.tsx +151 -0
- package/templates/ui/separator.tsx +25 -0
- package/templates/ui/sheet.tsx +120 -0
- package/templates/ui/sidebar.tsx +684 -0
- package/templates/ui/skeleton.tsx +7 -0
- package/templates/ui/slider.tsx +24 -0
- package/templates/ui/sonner.tsx +29 -0
- package/templates/ui/spinner.tsx +15 -0
- package/templates/ui/switch.tsx +28 -0
- package/templates/ui/table.tsx +93 -0
- package/templates/ui/tabs.tsx +54 -0
- package/templates/ui/textarea.tsx +20 -0
- package/templates/ui/toast.tsx +127 -0
- package/templates/ui/toggle-group.tsx +56 -0
- package/templates/ui/toggle.tsx +43 -0
- package/templates/ui/tooltip.tsx +31 -0
- package/templates/ui/use-mobile.tsx +19 -0
- package/templates/ui/video-upload-field.tsx +368 -0
- package/dist/chunk-G4KI4DVB.js +0 -179
- package/dist/chunk-G4KI4DVB.js.map +0 -1
- package/dist/chunk-NKRQYAS6.js +0 -260
- package/dist/chunk-NKRQYAS6.js.map +0 -1
- package/dist/chunk-QLVSHP7X.js +0 -235
- package/dist/chunk-QLVSHP7X.js.map +0 -1
- package/dist/chunk-WY6BC55D.js +0 -357
- package/dist/chunk-WY6BC55D.js.map +0 -1
- package/dist/config/index.d.ts +0 -93
- package/dist/config/index.js +0 -58
- package/dist/config/index.js.map +0 -1
- package/dist/core/index.d.ts +0 -415
- package/dist/core/index.js +0 -906
- package/dist/core/index.js.map +0 -1
- package/dist/import-resolver-BaZ-rzkH.d.ts +0 -123
- package/dist/logger-awLb347n.d.ts +0 -81
- package/dist/plugins/index.d.ts +0 -213
- package/dist/plugins/index.js +0 -365
- package/dist/plugins/index.js.map +0 -1
- package/dist/types-ByX_gl6y.d.ts +0 -232
- package/dist/types-eI549DEG.d.ts +0 -331
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'
|
|
4
|
+
import { forwardRef } from 'react'
|
|
5
|
+
import { cn } from '../../lib/tiptap-utils'
|
|
6
|
+
import './dropdown-menu.scss'
|
|
7
|
+
|
|
8
|
+
function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
|
|
9
|
+
return <DropdownMenuPrimitive.Root modal={false} {...props} />
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function DropdownMenuPortal({
|
|
13
|
+
...props
|
|
14
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
|
|
15
|
+
return <DropdownMenuPrimitive.Portal {...props} />
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const DropdownMenuTrigger = forwardRef<
|
|
19
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Trigger>,
|
|
20
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>
|
|
21
|
+
>(({ ...props }, ref) => <DropdownMenuPrimitive.Trigger ref={ref} {...props} />)
|
|
22
|
+
DropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName
|
|
23
|
+
|
|
24
|
+
const DropdownMenuGroup = DropdownMenuPrimitive.Group
|
|
25
|
+
|
|
26
|
+
const DropdownMenuSub = DropdownMenuPrimitive.Sub
|
|
27
|
+
|
|
28
|
+
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
|
|
29
|
+
|
|
30
|
+
const DropdownMenuItem = DropdownMenuPrimitive.Item
|
|
31
|
+
|
|
32
|
+
const DropdownMenuSubTrigger = DropdownMenuPrimitive.SubTrigger
|
|
33
|
+
|
|
34
|
+
const DropdownMenuSubContent = forwardRef<
|
|
35
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.SubContent>,
|
|
36
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent> & {
|
|
37
|
+
portal?: boolean | React.ComponentProps<typeof DropdownMenuPortal>
|
|
38
|
+
}
|
|
39
|
+
>(({ className, portal = true, ...props }, ref) => {
|
|
40
|
+
const content = (
|
|
41
|
+
<DropdownMenuPrimitive.SubContent
|
|
42
|
+
ref={ref}
|
|
43
|
+
className={cn('tiptap-dropdown-menu', className)}
|
|
44
|
+
{...props}
|
|
45
|
+
/>
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return portal ? (
|
|
49
|
+
<DropdownMenuPortal {...(typeof portal === 'object' ? portal : {})}>
|
|
50
|
+
{content}
|
|
51
|
+
</DropdownMenuPortal>
|
|
52
|
+
) : (
|
|
53
|
+
content
|
|
54
|
+
)
|
|
55
|
+
})
|
|
56
|
+
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName
|
|
57
|
+
|
|
58
|
+
const DropdownMenuContent = forwardRef<
|
|
59
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Content>,
|
|
60
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> & {
|
|
61
|
+
portal?: boolean
|
|
62
|
+
}
|
|
63
|
+
>(({ className, sideOffset = 4, portal = false, ...props }, ref) => {
|
|
64
|
+
const content = (
|
|
65
|
+
<DropdownMenuPrimitive.Content
|
|
66
|
+
ref={ref}
|
|
67
|
+
sideOffset={sideOffset}
|
|
68
|
+
onCloseAutoFocus={(e) => e.preventDefault()}
|
|
69
|
+
className={cn('tiptap-dropdown-menu', className)}
|
|
70
|
+
{...props}
|
|
71
|
+
/>
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
return portal ? (
|
|
75
|
+
<DropdownMenuPortal {...(typeof portal === 'object' ? portal : {})}>
|
|
76
|
+
{content}
|
|
77
|
+
</DropdownMenuPortal>
|
|
78
|
+
) : (
|
|
79
|
+
content
|
|
80
|
+
)
|
|
81
|
+
})
|
|
82
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
|
|
83
|
+
|
|
84
|
+
export {
|
|
85
|
+
DropdownMenu,
|
|
86
|
+
DropdownMenuTrigger,
|
|
87
|
+
DropdownMenuContent,
|
|
88
|
+
DropdownMenuItem,
|
|
89
|
+
DropdownMenuGroup,
|
|
90
|
+
DropdownMenuSub,
|
|
91
|
+
DropdownMenuPortal,
|
|
92
|
+
DropdownMenuSubContent,
|
|
93
|
+
DropdownMenuSubTrigger,
|
|
94
|
+
DropdownMenuRadioGroup
|
|
95
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dropdown-menu'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './input'
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--tiptap-input-placeholder: var(--tt-gray-light-a-400);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.dark {
|
|
6
|
+
--tiptap-input-placeholder: var(--tt-gray-dark-a-400);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.tiptap-input {
|
|
10
|
+
display: block;
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: 2rem;
|
|
13
|
+
font-size: 0.875rem;
|
|
14
|
+
font-weight: 400;
|
|
15
|
+
line-height: 1.5;
|
|
16
|
+
padding: 0.375rem 0.5rem;
|
|
17
|
+
border-radius: 0.375rem;
|
|
18
|
+
background: none;
|
|
19
|
+
appearance: none;
|
|
20
|
+
outline: none;
|
|
21
|
+
|
|
22
|
+
&::placeholder {
|
|
23
|
+
color: var(--tiptap-input-placeholder);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.tiptap-input-clamp {
|
|
28
|
+
min-width: 12rem;
|
|
29
|
+
padding-right: 0;
|
|
30
|
+
|
|
31
|
+
text-overflow: ellipsis;
|
|
32
|
+
white-space: nowrap;
|
|
33
|
+
|
|
34
|
+
&:focus {
|
|
35
|
+
text-overflow: clip;
|
|
36
|
+
overflow: visible;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.tiptap-input-group {
|
|
41
|
+
position: relative;
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-wrap: wrap;
|
|
44
|
+
align-items: stretch;
|
|
45
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { cn } from '../../lib/tiptap-utils'
|
|
4
|
+
import './input.scss'
|
|
5
|
+
|
|
6
|
+
function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
|
|
7
|
+
return <input type={type} className={cn('tiptap-input', className)} {...props} />
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function InputGroup({ className, children, ...props }: React.ComponentProps<'div'>) {
|
|
11
|
+
return (
|
|
12
|
+
<div className={cn('tiptap-input-group', className)} {...props}>
|
|
13
|
+
{children}
|
|
14
|
+
</div>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { Input, InputGroup }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './popover'
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
.tiptap-popover {
|
|
2
|
+
--tt-popover-bg-color: var(--white);
|
|
3
|
+
--tt-popover-border-color: var(--tt-gray-light-a-100);
|
|
4
|
+
--tt-popover-text-color: var(--tt-gray-light-a-600);
|
|
5
|
+
|
|
6
|
+
.dark & {
|
|
7
|
+
--tt-popover-border-color: var(--tt-gray-dark-a-50);
|
|
8
|
+
--tt-popover-bg-color: var(--tt-gray-dark-50);
|
|
9
|
+
--tt-popover-text-color: var(--tt-gray-dark-a-600);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* --------------------------------------------
|
|
14
|
+
--------- POPOVER STYLING SETTINGS -----------
|
|
15
|
+
-------------------------------------------- */
|
|
16
|
+
.tiptap-popover {
|
|
17
|
+
z-index: 50;
|
|
18
|
+
outline: none;
|
|
19
|
+
transform-origin: var(--radix-popover-content-transform-origin);
|
|
20
|
+
max-height: var(--radix-popover-content-available-height);
|
|
21
|
+
|
|
22
|
+
> * {
|
|
23
|
+
max-height: var(--radix-popover-content-available-height);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Animation states */
|
|
27
|
+
&[data-state="open"] {
|
|
28
|
+
animation:
|
|
29
|
+
fadeIn 150ms cubic-bezier(0.16, 1, 0.3, 1),
|
|
30
|
+
zoomIn 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&[data-state="closed"] {
|
|
34
|
+
animation:
|
|
35
|
+
fadeOut 150ms cubic-bezier(0.16, 1, 0.3, 1),
|
|
36
|
+
zoomOut 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Position-based animations */
|
|
40
|
+
&[data-side="top"],
|
|
41
|
+
&[data-side="top-start"],
|
|
42
|
+
&[data-side="top-end"] {
|
|
43
|
+
animation: slideFromBottom 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&[data-side="right"],
|
|
47
|
+
&[data-side="right-start"],
|
|
48
|
+
&[data-side="right-end"] {
|
|
49
|
+
animation: slideFromLeft 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&[data-side="bottom"],
|
|
53
|
+
&[data-side="bottom-start"],
|
|
54
|
+
&[data-side="bottom-end"] {
|
|
55
|
+
animation: slideFromTop 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&[data-side="left"],
|
|
59
|
+
&[data-side="left-start"],
|
|
60
|
+
&[data-side="left-end"] {
|
|
61
|
+
animation: slideFromRight 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover'
|
|
4
|
+
import { cn } from '../../lib/tiptap-utils'
|
|
5
|
+
import './popover.scss'
|
|
6
|
+
|
|
7
|
+
function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>) {
|
|
8
|
+
return <PopoverPrimitive.Root {...props} />
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
|
12
|
+
return <PopoverPrimitive.Trigger {...props} />
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function PopoverContent({
|
|
16
|
+
className,
|
|
17
|
+
align = 'center',
|
|
18
|
+
sideOffset = 4,
|
|
19
|
+
...props
|
|
20
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
|
|
21
|
+
return (
|
|
22
|
+
<PopoverPrimitive.Portal>
|
|
23
|
+
<PopoverPrimitive.Content
|
|
24
|
+
align={align}
|
|
25
|
+
sideOffset={sideOffset}
|
|
26
|
+
className={cn('tiptap-popover', className)}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
</PopoverPrimitive.Portal>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { Popover, PopoverTrigger, PopoverContent }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './separator'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
.tiptap-separator {
|
|
2
|
+
--tt-link-border-color: var(--tt-gray-light-a-200);
|
|
3
|
+
|
|
4
|
+
.dark & {
|
|
5
|
+
--tt-link-border-color: var(--tt-gray-dark-a-200);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.tiptap-separator {
|
|
10
|
+
flex-shrink: 0;
|
|
11
|
+
background-color: var(--tt-link-border-color);
|
|
12
|
+
|
|
13
|
+
&[data-orientation="horizontal"] {
|
|
14
|
+
height: 1px;
|
|
15
|
+
width: 100%;
|
|
16
|
+
margin: 0.5rem 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&[data-orientation="vertical"] {
|
|
20
|
+
height: 1.5rem;
|
|
21
|
+
width: 1px;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { forwardRef } from 'react'
|
|
4
|
+
import './separator.scss'
|
|
5
|
+
import { cn } from '../../lib/tiptap-utils'
|
|
6
|
+
|
|
7
|
+
export type Orientation = 'horizontal' | 'vertical'
|
|
8
|
+
|
|
9
|
+
export interface SeparatorProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
10
|
+
orientation?: Orientation
|
|
11
|
+
decorative?: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const Separator = forwardRef<HTMLDivElement, SeparatorProps>(
|
|
15
|
+
({ decorative, orientation = 'vertical', className, ...divProps }, ref) => {
|
|
16
|
+
const ariaOrientation = orientation === 'vertical' ? orientation : undefined
|
|
17
|
+
const semanticProps = decorative
|
|
18
|
+
? { role: 'none' }
|
|
19
|
+
: { 'aria-orientation': ariaOrientation, role: 'separator' }
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div
|
|
23
|
+
className={cn('tiptap-separator', className)}
|
|
24
|
+
data-orientation={orientation}
|
|
25
|
+
{...semanticProps}
|
|
26
|
+
{...divProps}
|
|
27
|
+
ref={ref}
|
|
28
|
+
/>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
Separator.displayName = 'Separator'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './spacer'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
export type SpacerOrientation = 'horizontal' | 'vertical'
|
|
4
|
+
|
|
5
|
+
export interface SpacerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
6
|
+
orientation?: SpacerOrientation
|
|
7
|
+
size?: string | number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function Spacer({ orientation = 'horizontal', size, style = {}, ...props }: SpacerProps) {
|
|
11
|
+
const computedStyle = {
|
|
12
|
+
...style,
|
|
13
|
+
...(orientation === 'horizontal' && !size && { flex: 1 }),
|
|
14
|
+
...(size && {
|
|
15
|
+
width: orientation === 'vertical' ? '1px' : size,
|
|
16
|
+
height: orientation === 'horizontal' ? '1px' : size
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return <div {...props} style={computedStyle} />
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './toolbar'
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--tt-toolbar-height: 2.75rem;
|
|
3
|
+
--tt-safe-area-bottom: env(safe-area-inset-bottom, 0px);
|
|
4
|
+
--tt-toolbar-bg-color: var(--white);
|
|
5
|
+
--tt-toolbar-border-color: var(--tt-gray-light-a-100);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.dark {
|
|
9
|
+
--tt-toolbar-bg-color: var(--black);
|
|
10
|
+
--tt-toolbar-border-color: var(--tt-gray-dark-a-50);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.tiptap-toolbar {
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
gap: 0.25rem;
|
|
17
|
+
|
|
18
|
+
&-group {
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
gap: 0.125rem;
|
|
22
|
+
|
|
23
|
+
&:empty {
|
|
24
|
+
display: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&:empty + .tiptap-separator,
|
|
28
|
+
.tiptap-separator + &:empty {
|
|
29
|
+
display: none;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&[data-variant="fixed"] {
|
|
34
|
+
position: sticky;
|
|
35
|
+
top: 0;
|
|
36
|
+
z-index: 10;
|
|
37
|
+
width: 100%;
|
|
38
|
+
min-height: var(--tt-toolbar-height);
|
|
39
|
+
background: var(--tt-toolbar-bg-color);
|
|
40
|
+
border-bottom: 1px solid var(--tt-toolbar-border-color);
|
|
41
|
+
padding: 0 0.5rem;
|
|
42
|
+
overflow-x: auto;
|
|
43
|
+
overscroll-behavior-x: contain;
|
|
44
|
+
-webkit-overflow-scrolling: touch;
|
|
45
|
+
scrollbar-width: none;
|
|
46
|
+
-ms-overflow-style: none;
|
|
47
|
+
|
|
48
|
+
&::-webkit-scrollbar {
|
|
49
|
+
display: none;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@media (max-width: 480px) {
|
|
53
|
+
position: absolute;
|
|
54
|
+
top: auto;
|
|
55
|
+
height: calc(var(--tt-toolbar-height) + var(--tt-safe-area-bottom));
|
|
56
|
+
border-top: 1px solid var(--tt-toolbar-border-color);
|
|
57
|
+
border-bottom: none;
|
|
58
|
+
padding: 0 0.5rem var(--tt-safe-area-bottom);
|
|
59
|
+
flex-wrap: nowrap;
|
|
60
|
+
justify-content: flex-start;
|
|
61
|
+
|
|
62
|
+
.tiptap-toolbar-group {
|
|
63
|
+
flex: 0 0 auto;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&[data-variant="floating"] {
|
|
69
|
+
--tt-toolbar-padding: 0.125rem;
|
|
70
|
+
--tt-toolbar-border-width: 1px;
|
|
71
|
+
|
|
72
|
+
padding: 0.188rem;
|
|
73
|
+
border-radius: calc(
|
|
74
|
+
var(--tt-toolbar-padding) + var(--tt-radius-lg) +
|
|
75
|
+
var(--tt-toolbar-border-width)
|
|
76
|
+
);
|
|
77
|
+
border: var(--tt-toolbar-border-width) solid var(--tt-toolbar-border-color);
|
|
78
|
+
background-color: var(--tt-toolbar-bg-color);
|
|
79
|
+
box-shadow: var(--tt-shadow-elevated-md);
|
|
80
|
+
outline: none;
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
|
|
83
|
+
&[data-plain="true"] {
|
|
84
|
+
padding: 0;
|
|
85
|
+
border-radius: 0;
|
|
86
|
+
border: none;
|
|
87
|
+
box-shadow: none;
|
|
88
|
+
background-color: transparent;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@media screen and (max-width: 480px) {
|
|
92
|
+
width: 100%;
|
|
93
|
+
border-radius: 0;
|
|
94
|
+
border: none;
|
|
95
|
+
box-shadow: none;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { forwardRef, useCallback, useEffect, useRef, useState } from 'react'
|
|
4
|
+
import { Separator } from '../separator'
|
|
5
|
+
import './toolbar.scss'
|
|
6
|
+
import { useComposedRef } from '../../hooks/use-composed-ref'
|
|
7
|
+
import { useMenuNavigation } from '../../hooks/use-menu-navigation'
|
|
8
|
+
import { cn } from '../../lib/tiptap-utils'
|
|
9
|
+
|
|
10
|
+
type BaseProps = React.HTMLAttributes<HTMLDivElement>
|
|
11
|
+
|
|
12
|
+
interface ToolbarProps extends BaseProps {
|
|
13
|
+
variant?: 'floating' | 'fixed'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const useToolbarNavigation = (toolbarRef: React.RefObject<HTMLDivElement | null>) => {
|
|
17
|
+
const [items, setItems] = useState<HTMLElement[]>([])
|
|
18
|
+
|
|
19
|
+
const collectItems = useCallback(() => {
|
|
20
|
+
if (!toolbarRef.current) return []
|
|
21
|
+
return Array.from(
|
|
22
|
+
toolbarRef.current.querySelectorAll<HTMLElement>(
|
|
23
|
+
'button:not([disabled]), [role="button"]:not([disabled]), [tabindex="0"]:not([disabled])'
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
}, [toolbarRef])
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const toolbar = toolbarRef.current
|
|
30
|
+
if (!toolbar) return
|
|
31
|
+
|
|
32
|
+
const updateItems = () => setItems(collectItems())
|
|
33
|
+
|
|
34
|
+
updateItems()
|
|
35
|
+
const observer = new MutationObserver(updateItems)
|
|
36
|
+
observer.observe(toolbar, { childList: true, subtree: true })
|
|
37
|
+
|
|
38
|
+
return () => observer.disconnect()
|
|
39
|
+
}, [collectItems, toolbarRef])
|
|
40
|
+
|
|
41
|
+
const { selectedIndex } = useMenuNavigation<HTMLElement>({
|
|
42
|
+
containerRef: toolbarRef,
|
|
43
|
+
items,
|
|
44
|
+
orientation: 'horizontal',
|
|
45
|
+
onSelect: (el) => el.click(),
|
|
46
|
+
autoSelectFirstItem: false
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const toolbar = toolbarRef.current
|
|
51
|
+
if (!toolbar) return
|
|
52
|
+
|
|
53
|
+
const handleFocus = (e: FocusEvent) => {
|
|
54
|
+
const target = e.target as HTMLElement
|
|
55
|
+
if (toolbar.contains(target)) target.setAttribute('data-focus-visible', 'true')
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const handleBlur = (e: FocusEvent) => {
|
|
59
|
+
const target = e.target as HTMLElement
|
|
60
|
+
if (toolbar.contains(target)) target.removeAttribute('data-focus-visible')
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
toolbar.addEventListener('focus', handleFocus, true)
|
|
64
|
+
toolbar.addEventListener('blur', handleBlur, true)
|
|
65
|
+
|
|
66
|
+
return () => {
|
|
67
|
+
toolbar.removeEventListener('focus', handleFocus, true)
|
|
68
|
+
toolbar.removeEventListener('blur', handleBlur, true)
|
|
69
|
+
}
|
|
70
|
+
}, [toolbarRef])
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (selectedIndex !== undefined && items[selectedIndex]) {
|
|
74
|
+
items[selectedIndex].focus()
|
|
75
|
+
}
|
|
76
|
+
}, [selectedIndex, items])
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const Toolbar = forwardRef<HTMLDivElement, ToolbarProps>(
|
|
80
|
+
({ children, className, variant = 'fixed', ...props }, ref) => {
|
|
81
|
+
const toolbarRef = useRef<HTMLDivElement>(null)
|
|
82
|
+
const composedRef = useComposedRef(toolbarRef, ref)
|
|
83
|
+
useToolbarNavigation(toolbarRef)
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<div
|
|
87
|
+
ref={composedRef}
|
|
88
|
+
role="toolbar"
|
|
89
|
+
aria-label="toolbar"
|
|
90
|
+
data-variant={variant}
|
|
91
|
+
className={cn('tiptap-toolbar border-border!', className)}
|
|
92
|
+
{...props}
|
|
93
|
+
>
|
|
94
|
+
{children}
|
|
95
|
+
</div>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
Toolbar.displayName = 'Toolbar'
|
|
100
|
+
|
|
101
|
+
export const ToolbarGroup = forwardRef<HTMLDivElement, BaseProps>(
|
|
102
|
+
({ children, className, ...props }, ref) => (
|
|
103
|
+
<div ref={ref} role="group" className={cn('tiptap-toolbar-group', className)} {...props}>
|
|
104
|
+
{children}
|
|
105
|
+
</div>
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
ToolbarGroup.displayName = 'ToolbarGroup'
|
|
109
|
+
|
|
110
|
+
export const ToolbarSeparator = forwardRef<HTMLDivElement, BaseProps>(({ ...props }, ref) => (
|
|
111
|
+
<Separator ref={ref} orientation="vertical" decorative {...props} />
|
|
112
|
+
))
|
|
113
|
+
ToolbarSeparator.displayName = 'ToolbarSeparator'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './tooltip'
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
.tiptap-tooltip {
|
|
2
|
+
--tt-tooltip-bg: var(--tt-gray-light-900);
|
|
3
|
+
--tt-tooltip-text: var(--white);
|
|
4
|
+
--tt-kbd: var(--tt-gray-dark-a-400);
|
|
5
|
+
|
|
6
|
+
.dark & {
|
|
7
|
+
--tt-tooltip-bg: var(--white);
|
|
8
|
+
--tt-tooltip-text: var(--tt-gray-light-600);
|
|
9
|
+
--tt-kbd: var(--tt-gray-light-a-400);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.tiptap-tooltip {
|
|
14
|
+
z-index: 200;
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
border-radius: var(--tt-radius-md, 0.375rem);
|
|
17
|
+
background-color: var(--tt-tooltip-bg);
|
|
18
|
+
padding: 0.375rem 0.5rem;
|
|
19
|
+
font-size: 0.75rem;
|
|
20
|
+
font-weight: 500;
|
|
21
|
+
color: var(--tt-tooltip-text);
|
|
22
|
+
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
|
23
|
+
text-align: center;
|
|
24
|
+
|
|
25
|
+
kbd {
|
|
26
|
+
display: inline-block;
|
|
27
|
+
text-align: center;
|
|
28
|
+
vertical-align: baseline;
|
|
29
|
+
font-family:
|
|
30
|
+
ui-sans-serif,
|
|
31
|
+
system-ui,
|
|
32
|
+
-apple-system,
|
|
33
|
+
BlinkMacSystemFont,
|
|
34
|
+
"Segoe UI",
|
|
35
|
+
Roboto,
|
|
36
|
+
"Helvetica Neue",
|
|
37
|
+
Arial,
|
|
38
|
+
"Noto Sans",
|
|
39
|
+
sans-serif;
|
|
40
|
+
text-transform: capitalize;
|
|
41
|
+
color: var(--tt-kbd);
|
|
42
|
+
}
|
|
43
|
+
}
|