@livepreso/react-plugin-textfield 0.0.2

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.
Files changed (176) hide show
  1. package/.lintstagedrc.js +6 -0
  2. package/.rush/temp/shrinkwrap-deps.json +311 -0
  3. package/.vscode/settings.json +22 -0
  4. package/CHANGELOG.json +17 -0
  5. package/CHANGELOG.md +9 -0
  6. package/components/BubbleMenu.js +181 -0
  7. package/components/BubbleMenu.module.scss +9 -0
  8. package/components/LinkEditDialog.js +105 -0
  9. package/components/LinkEditDialog.module.scss +171 -0
  10. package/components/Popover.js +43 -0
  11. package/components/Popover.module.scss +80 -0
  12. package/components/PrimaryToolbar.js +27 -0
  13. package/components/Select/Select.js +71 -0
  14. package/components/Select/Select.module.scss +100 -0
  15. package/components/Select/SelectGroup.js +37 -0
  16. package/components/Select/index.js +1 -0
  17. package/components/TableCellMenu.js +43 -0
  18. package/components/TableToolbar.js +41 -0
  19. package/components/Tooltip.js +34 -0
  20. package/components/Tooltip.module.scss +87 -0
  21. package/components/VerticalAlignToggle.js +65 -0
  22. package/components/color-picker/ColorPicker.js +28 -0
  23. package/components/color-picker/ColorPicker.module.scss +8 -0
  24. package/components/color-picker/ColorPickerChip.js +22 -0
  25. package/components/color-picker/ColorPickerChip.module.scss +25 -0
  26. package/components/color-picker/ColorPickerCombo.js +45 -0
  27. package/components/color-picker/ColorPickerCombo.module.scss +23 -0
  28. package/components/color-picker/TextColorIcon.js +18 -0
  29. package/components/editor-toolbars/EditorMenu.js +104 -0
  30. package/components/editor-toolbars/EditorMenu.module.scss +96 -0
  31. package/components/editor-toolbars/EditorToolbar.js +146 -0
  32. package/components/editor-toolbars/EditorToolbar.module.scss +75 -0
  33. package/components/editor-toolbars/MenuItem.js +24 -0
  34. package/components/editor-toolbars/SubMenu.js +50 -0
  35. package/components/editor-toolbars/ToolbarButton.js +26 -0
  36. package/components/editor-toolbars/ToolbarToggle.js +35 -0
  37. package/components/editor-toolbars/ToolbarToggleGroup.js +43 -0
  38. package/components/editor-toolbars/utils.js +7 -0
  39. package/components/hooks/use-presenter.js +5 -0
  40. package/components/style.module.scss +63 -0
  41. package/components/tiptap/ListItem.js +5 -0
  42. package/components/tiptap/Table.js +397 -0
  43. package/components/tiptap/TableCells.js +99 -0
  44. package/components/utils.js +84 -0
  45. package/configs/generate-toolbar-configuration.js +130 -0
  46. package/configs/generate-toolbar-options.js +96 -0
  47. package/configs/table-toolbar-configuration.js +187 -0
  48. package/configs/toolbar-configuration.js +330 -0
  49. package/constants.js +198 -0
  50. package/eslint.config.mjs +15 -0
  51. package/icons/AddColumnLeft.js +15 -0
  52. package/icons/AddColumnRight.js +15 -0
  53. package/icons/AddRowAbove.js +15 -0
  54. package/icons/AddRowBelow.js +15 -0
  55. package/icons/AlignHorizontalCenter.js +13 -0
  56. package/icons/AlignHorizontalLeft.js +13 -0
  57. package/icons/AlignHorizontalRight.js +13 -0
  58. package/icons/AlignVerticalBottom.js +13 -0
  59. package/icons/AlignVerticalCenter.js +13 -0
  60. package/icons/AlignVerticalTop.js +13 -0
  61. package/icons/Backspace.js +13 -0
  62. package/icons/Bold.js +14 -0
  63. package/icons/BorderAll.js +13 -0
  64. package/icons/BorderBottom.js +13 -0
  65. package/icons/BorderClear.js +13 -0
  66. package/icons/BorderHorizontal.js +13 -0
  67. package/icons/BorderInner.js +13 -0
  68. package/icons/BorderLeft.js +13 -0
  69. package/icons/BorderOuter.js +13 -0
  70. package/icons/BorderRight.js +13 -0
  71. package/icons/BorderTop.js +13 -0
  72. package/icons/BorderVertical.js +13 -0
  73. package/icons/Close.js +13 -0
  74. package/icons/Delete.js +13 -0
  75. package/icons/EvenlyDistribute.js +14 -0
  76. package/icons/FitWidth.js +13 -0
  77. package/icons/FitWidthArrows.js +21 -0
  78. package/icons/FormatAlignCenter.js +13 -0
  79. package/icons/FormatAlignJustify.js +13 -0
  80. package/icons/FormatAlignLeft.js +13 -0
  81. package/icons/FormatAlignRight.js +13 -0
  82. package/icons/FormatBold.js +13 -0
  83. package/icons/FormatClear.js +13 -0
  84. package/icons/FormatColorFill.js +13 -0
  85. package/icons/FormatColorText.js +13 -0
  86. package/icons/FormatItalic.js +13 -0
  87. package/icons/FormatLineSpacing.js +13 -0
  88. package/icons/FormatListBulleted.js +13 -0
  89. package/icons/FormatListNumbered.js +13 -0
  90. package/icons/FormatStrikethrough.js +13 -0
  91. package/icons/FormatUnderlined.js +13 -0
  92. package/icons/HorizontalRule.js +13 -0
  93. package/icons/Italic.js +14 -0
  94. package/icons/ItalicIcon.js +18 -0
  95. package/icons/Link.js +13 -0
  96. package/icons/LinkOff.js +13 -0
  97. package/icons/MergeCells.js +14 -0
  98. package/icons/Redo.js +13 -0
  99. package/icons/RemoveColumnOutline.js +28 -0
  100. package/icons/RemoveRowOutline.js +25 -0
  101. package/icons/SplitCells.js +14 -0
  102. package/icons/SplitScene.js +13 -0
  103. package/icons/Subscript.js +13 -0
  104. package/icons/Superscript.js +13 -0
  105. package/icons/Underline.js +14 -0
  106. package/icons/Undo.js +13 -0
  107. package/icons/VerticalAlignBottom.js +13 -0
  108. package/icons/VerticalAlignCenter.js +13 -0
  109. package/icons/VerticalAlignTop.js +13 -0
  110. package/icons/add_column_left.svg +6 -0
  111. package/icons/add_column_right.svg +6 -0
  112. package/icons/add_row_above.svg +6 -0
  113. package/icons/add_row_below.svg +6 -0
  114. package/icons/align_horizontal_center.svg +1 -0
  115. package/icons/align_horizontal_left.svg +1 -0
  116. package/icons/align_horizontal_right.svg +1 -0
  117. package/icons/align_vertical_bottom.svg +1 -0
  118. package/icons/align_vertical_center.svg +1 -0
  119. package/icons/align_vertical_top.svg +1 -0
  120. package/icons/backspace.svg +1 -0
  121. package/icons/bold.svg +1 -0
  122. package/icons/border_all.svg +1 -0
  123. package/icons/border_bottom.svg +1 -0
  124. package/icons/border_clear.svg +1 -0
  125. package/icons/border_horizontal.svg +1 -0
  126. package/icons/border_inner.svg +1 -0
  127. package/icons/border_left.svg +1 -0
  128. package/icons/border_outer.svg +1 -0
  129. package/icons/border_right.svg +1 -0
  130. package/icons/border_top.svg +1 -0
  131. package/icons/border_vertical.svg +1 -0
  132. package/icons/close.svg +1 -0
  133. package/icons/delete.svg +1 -0
  134. package/icons/evenly_distribute.svg +5 -0
  135. package/icons/fit_width.svg +1 -0
  136. package/icons/fit_width_arrows.svg +12 -0
  137. package/icons/format_align_center.svg +1 -0
  138. package/icons/format_align_justify.svg +1 -0
  139. package/icons/format_align_left.svg +1 -0
  140. package/icons/format_align_right.svg +1 -0
  141. package/icons/format_bold.svg +1 -0
  142. package/icons/format_clear.svg +1 -0
  143. package/icons/format_color_fill.svg +1 -0
  144. package/icons/format_color_text.svg +5 -0
  145. package/icons/format_color_text_ungrouped.svg +6 -0
  146. package/icons/format_italic.svg +1 -0
  147. package/icons/format_line_spacing.svg +1 -0
  148. package/icons/format_list_bulleted.svg +1 -0
  149. package/icons/format_list_numbered.svg +1 -0
  150. package/icons/format_strikethrough.svg +1 -0
  151. package/icons/format_underlined.svg +1 -0
  152. package/icons/horizontal_rule.svg +1 -0
  153. package/icons/index.js +191 -0
  154. package/icons/italic.svg +1 -0
  155. package/icons/link.svg +1 -0
  156. package/icons/link_off.svg +1 -0
  157. package/icons/merge_cells.svg +5 -0
  158. package/icons/redo.svg +1 -0
  159. package/icons/remove_column_outline.svg +20 -0
  160. package/icons/remove_row_outline.svg +17 -0
  161. package/icons/split_cells.svg +5 -0
  162. package/icons/split_scene.svg +1 -0
  163. package/icons/subscript.svg +1 -0
  164. package/icons/superscript.svg +1 -0
  165. package/icons/underline.svg +1 -0
  166. package/icons/undo.svg +1 -0
  167. package/icons/vertical_align_bottom.svg +1 -0
  168. package/icons/vertical_align_center.svg +1 -0
  169. package/icons/vertical_align_top.svg +1 -0
  170. package/index.js +334 -0
  171. package/index.module.scss +106 -0
  172. package/package.json +63 -0
  173. package/scripts/extract-svg.js +288 -0
  174. package/utils/color-utils.js +42 -0
  175. package/utils/generate-vertical-alignment-icon.js +22 -0
  176. package/utils/generateCustomExtensions.js +49 -0
@@ -0,0 +1,105 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { Dialog } from "radix-ui";
3
+ import style from "./LinkEditDialog.module.scss";
4
+ import classNames from "classnames";
5
+ import { Close } from "../icons";
6
+ import { ToolbarToggle } from "./editor-toolbars/ToolbarToggle";
7
+
8
+ const LinkEditDialog = ({
9
+ icon,
10
+ active,
11
+ label,
12
+ id,
13
+ onChange,
14
+ value = "https://www.livepreso.com/",
15
+ }) => {
16
+ const div = window.Bridge.UI.overlay;
17
+
18
+ const [urlInput, setUrlInput] = useState("");
19
+ const [open, setOpen] = useState(false);
20
+
21
+ useEffect(() => setUrlInput(value || ""), [value]);
22
+
23
+ const submitInput = () => {
24
+ onChange(urlInput);
25
+ };
26
+
27
+ const checkForEnter = (event) => {
28
+ if (event.key === "Enter") {
29
+ onChange(urlInput);
30
+ setOpen(false);
31
+ }
32
+ };
33
+
34
+ return (
35
+ <Dialog.Root open={open} onOpenChange={setOpen}>
36
+ <Dialog.Trigger asChild>
37
+ <ToolbarToggle
38
+ key={id}
39
+ label={label}
40
+ icon={icon}
41
+ disabled={false}
42
+ pressed={active}
43
+ />
44
+ </Dialog.Trigger>
45
+
46
+ <Dialog.Portal container={div}>
47
+ <Dialog.Overlay className={style.overlay} />
48
+ <Dialog.Content className={style.content}>
49
+ <div className={style.titleRow}>
50
+ <Dialog.Title className={style.title}>
51
+ Insert / Edit link
52
+ </Dialog.Title>
53
+
54
+ <Dialog.Close asChild>
55
+ <button className={classNames(style.button, style.iconButton)}>
56
+ <Close />
57
+ </button>
58
+ </Dialog.Close>
59
+ </div>
60
+
61
+ <Dialog.Description className={style.description}>
62
+ Links should include full https:// syntax. Click save when you're
63
+ done.
64
+ </Dialog.Description>
65
+
66
+ <fieldset className={style.fieldset}>
67
+ <label className={style.label} htmlFor="name">
68
+ URL
69
+ </label>
70
+ <input
71
+ className={style.input}
72
+ id="url"
73
+ value={urlInput}
74
+ onChange={(e) => {
75
+ let value = e.target.value;
76
+ if (!value.startsWith("http")) value = `https://${value}`;
77
+ setUrlInput(value);
78
+ }}
79
+ onKeyDown={checkForEnter}
80
+ />
81
+ </fieldset>
82
+
83
+ <div className={style.buttonRow}>
84
+ <Dialog.Close asChild>
85
+ <button className={style.button} aria-label="Close">
86
+ Cancel
87
+ </button>
88
+ </Dialog.Close>
89
+ <Dialog.Close asChild>
90
+ <button
91
+ aria-label="Save"
92
+ onClick={submitInput}
93
+ className={classNames(style.button, style.primary)}
94
+ >
95
+ Save
96
+ </button>
97
+ </Dialog.Close>
98
+ </div>
99
+ </Dialog.Content>
100
+ </Dialog.Portal>
101
+ </Dialog.Root>
102
+ );
103
+ };
104
+
105
+ export default LinkEditDialog;
@@ -0,0 +1,171 @@
1
+ @import "./style.module.scss";
2
+
3
+ :global(.sp-presenter-overlay) {
4
+ .overlay {
5
+ background-color: var(--sp-toolbar-modal-bg-color);
6
+ position: fixed;
7
+ inset: 0;
8
+ animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
9
+ }
10
+
11
+ // Specificity below is required to beat the unset
12
+ // found in index.module.scss
13
+ .content {
14
+ @extend %root;
15
+ position: fixed;
16
+ top: 50%;
17
+ left: 50%;
18
+ flex-direction: column;
19
+ transform: translate(-50%, -50%);
20
+ width: 90vw;
21
+ max-width: 500px;
22
+ max-height: 85vh;
23
+ padding: 15px;
24
+ animation: contentShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
25
+
26
+ &:focus {
27
+ outline: none;
28
+ }
29
+
30
+ .title-row {
31
+ display: flex;
32
+ justify-content: space-between;
33
+ }
34
+
35
+ .title {
36
+ margin: 0;
37
+ color: var(--sp-toolbar-color);
38
+ font-size: 20px;
39
+ line-height: 1.3em;
40
+ font-weight: 400;
41
+ }
42
+
43
+ .description {
44
+ margin: 10px 0 20px;
45
+ color: var(--sp-toolbar-highlight-color);
46
+ font-size: 14px;
47
+ line-height: 1.3em;
48
+ font-weight: 400;
49
+ }
50
+
51
+ .fieldset {
52
+ display: flex;
53
+ flex-direction: column;
54
+ margin-bottom: 15px;
55
+ }
56
+
57
+ .label {
58
+ color: var(--sp-toolbar-color);
59
+ font-size: 14px;
60
+ line-height: 1.3em;
61
+ font-weight: 400;
62
+ }
63
+
64
+ .input {
65
+ flex: none;
66
+ display: inline-flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ border-radius: 4px;
70
+ padding: 0 10px;
71
+ font-size: 16px;
72
+ line-height: 24;
73
+ font-weight: 400;
74
+ color: var(--sp-toolbar-color);
75
+ border: 1px solid var(--sp-toolbar-highlight-color);
76
+ // box-shadow: 0 0 0 1px var(--violet-7);
77
+ height: 35px;
78
+ }
79
+ .input:focus {
80
+ border: 1px solid var(--sp-toolbar-focus-color);
81
+ // box-shadow: 0 0 0 2px var(--violet-8);
82
+ }
83
+
84
+ .button-row {
85
+ display: flex;
86
+ margin-top: 10px;
87
+ justify-content: flex-end;
88
+
89
+ .button {
90
+ &:not(:first-child) {
91
+ margin-left: 8px;
92
+ }
93
+ }
94
+ }
95
+
96
+ .button {
97
+ display: inline-flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ border-radius: 6px;
101
+ padding: 4px 16px;
102
+ font-size: 14px;
103
+ line-height: 24px;
104
+ font-weight: 700;
105
+ user-select: none;
106
+ color: var(--sp-toolbar-color);
107
+ background-color: var(--sp-toolbar-button);
108
+ cursor: pointer;
109
+
110
+ &:hover {
111
+ background-color: var(--sp-toolbar-button-hover);
112
+ }
113
+
114
+ &:focus:not(:focus-visible) {
115
+ outline: 0;
116
+ }
117
+
118
+ &:focus-visible {
119
+ outline: 2px solid var(--sp-toolbar-button);
120
+ outline-offset: 2px;
121
+ }
122
+
123
+ &[data-disabled],
124
+ &[disabled] {
125
+ @extend %disabled;
126
+ }
127
+
128
+ &.primary {
129
+ color: var(--sp-toolbar-color-white);
130
+ background-color: var(--sp-toolbar-button-primary);
131
+
132
+ &:focus-visible {
133
+ outline-color: var(--sp-toolbar-button-primary);
134
+ }
135
+
136
+ &:hover {
137
+ background-color: var(--sp-toolbar-button-primary-hover);
138
+ }
139
+ }
140
+
141
+ &.icon-button {
142
+ padding: 6px;
143
+ background-color: transparent;
144
+
145
+ &:hover {
146
+ background-color: var(--sp-toolbar-button-hover);
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ @keyframes overlayShow {
154
+ from {
155
+ opacity: 0;
156
+ }
157
+ to {
158
+ opacity: 1;
159
+ }
160
+ }
161
+
162
+ @keyframes contentShow {
163
+ from {
164
+ opacity: 0;
165
+ transform: translate(-50%, -48%) scale(0.96);
166
+ }
167
+ to {
168
+ opacity: 1;
169
+ transform: translate(-50%, -50%) scale(1);
170
+ }
171
+ }
@@ -0,0 +1,43 @@
1
+ import React from "react";
2
+
3
+ import style from "./Popover.module.scss";
4
+ import { Popover as PopoverBase } from "radix-ui";
5
+
6
+ export function Popover({
7
+ tooltip,
8
+ colors = [],
9
+ active,
10
+ onChange,
11
+ // Use this when the popover appears within a dropdown menu (or similar)
12
+ // to prevent it closing when the mouse moved outside of the trigger.
13
+ preventInteractOutside = false,
14
+ trigger = "open",
15
+ triggerClassName,
16
+ children,
17
+ }) {
18
+ const div = window.Bridge.UI.overlay;
19
+
20
+ return (
21
+ <PopoverBase.Root>
22
+ <PopoverBase.Trigger className={triggerClassName} asChild>
23
+ {trigger}
24
+ </PopoverBase.Trigger>
25
+
26
+ <PopoverBase.Portal container={div}>
27
+ <PopoverBase.Content
28
+ collisionBoundary={div}
29
+ onOpenAutoFocus={(e) => e.preventDefault()} // Prevents focus moving to the content on open
30
+ onCloseAutoFocus={(e) => e.preventDefault()} // Prevents focus moving to the trigger on close
31
+ onInteractOutside={(e) =>
32
+ preventInteractOutside && e.preventDefault()
33
+ } // Prevents closing when inside DropdownMenu
34
+ className={style.content}
35
+ sideOffset={5}
36
+ >
37
+ <div className={style.contentContainer}>{children}</div>
38
+ <PopoverBase.Arrow className={style.arrow} />
39
+ </PopoverBase.Content>
40
+ </PopoverBase.Portal>
41
+ </PopoverBase.Root>
42
+ );
43
+ }
@@ -0,0 +1,80 @@
1
+ @import "./style.module.scss";
2
+
3
+ :global(.sp-presenter-overlay) {
4
+ .content {
5
+ @extend %root;
6
+ padding: 2px;
7
+ animation-duration: 400ms;
8
+ animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
9
+ will-change: transform, opacity;
10
+
11
+ &-container {
12
+ overflow: hidden;
13
+ border-radius: 5px;
14
+ }
15
+ }
16
+
17
+ .content:focus {
18
+ @extend %focus;
19
+ }
20
+ .content[data-state="open"][data-side="top"] {
21
+ animation-name: slideDownAndFade;
22
+ }
23
+ .content[data-state="open"][data-side="right"] {
24
+ animation-name: slideLeftAndFade;
25
+ }
26
+ .content[data-state="open"][data-side="bottom"] {
27
+ animation-name: slideUpAndFade;
28
+ }
29
+ .content[data-state="open"][data-side="left"] {
30
+ animation-name: slideRightAndFade;
31
+ }
32
+
33
+ .arrow {
34
+ fill: white;
35
+ }
36
+ }
37
+
38
+ @keyframes slideUpAndFade {
39
+ from {
40
+ opacity: 0;
41
+ transform: translateY(2px);
42
+ }
43
+ to {
44
+ opacity: 1;
45
+ transform: translateY(0);
46
+ }
47
+ }
48
+
49
+ @keyframes slideRightAndFade {
50
+ from {
51
+ opacity: 0;
52
+ transform: translateX(-2px);
53
+ }
54
+ to {
55
+ opacity: 1;
56
+ transform: translateX(0);
57
+ }
58
+ }
59
+
60
+ @keyframes slideDownAndFade {
61
+ from {
62
+ opacity: 0;
63
+ transform: translateY(-2px);
64
+ }
65
+ to {
66
+ opacity: 1;
67
+ transform: translateY(0);
68
+ }
69
+ }
70
+
71
+ @keyframes slideLeftAndFade {
72
+ from {
73
+ opacity: 0;
74
+ transform: translateX(2px);
75
+ }
76
+ to {
77
+ opacity: 1;
78
+ transform: translateX(0);
79
+ }
80
+ }
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+
3
+ import { BubbleMenu } from "./BubbleMenu";
4
+ import { EditorToolbar } from "./editor-toolbars/EditorToolbar";
5
+
6
+ export function PrimaryToolbar({
7
+ editor,
8
+ editorState,
9
+ userSelections,
10
+ configuration = [],
11
+ maskSelector,
12
+ }) {
13
+ return (
14
+ <BubbleMenu
15
+ editor={editor}
16
+ options={{ placement: "top-start", maskSelector }}
17
+ shouldShow={({ editor }) => editor.isFocused}
18
+ >
19
+ <EditorToolbar
20
+ configuration={configuration}
21
+ editor={editor}
22
+ editorState={editorState}
23
+ userSelections={userSelections}
24
+ />
25
+ </BubbleMenu>
26
+ );
27
+ }
@@ -0,0 +1,71 @@
1
+ import React, { Fragment } from "react";
2
+
3
+ import classNames from "classnames";
4
+ import { Select as SelectBase } from "radix-ui";
5
+
6
+ import { ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons";
7
+
8
+ import style from "./Select.module.scss";
9
+ import { SelectGroup } from "./SelectGroup";
10
+
11
+ export function Select({
12
+ className,
13
+ options = [],
14
+ placeholder = "Select an option",
15
+ label = "Options",
16
+ onValueChange,
17
+ value,
18
+ }) {
19
+ const div = window.Bridge.UI.overlay;
20
+
21
+ const isGroupedOptions = Array.isArray(options[0]);
22
+
23
+ return (
24
+ <SelectBase.Root
25
+ value={value}
26
+ onValueChange={(value) => onValueChange(value)}
27
+ >
28
+ <SelectBase.Trigger
29
+ className={classNames(style.trigger, className)}
30
+ aria-label={label}
31
+ >
32
+ <SelectBase.Value placeholder={placeholder} />
33
+ <SelectBase.Icon className={style.icon}>
34
+ <ChevronDownIcon />
35
+ </SelectBase.Icon>
36
+ </SelectBase.Trigger>
37
+
38
+ <SelectBase.Portal container={div}>
39
+ <SelectBase.Content
40
+ collisionBoundary={div}
41
+ className={style.content}
42
+ onCloseAutoFocus={(e) => e.preventDefault()}
43
+ position="popper"
44
+ >
45
+ <SelectBase.ScrollUpButton className={style.scrollButton}>
46
+ <ChevronUpIcon />
47
+ </SelectBase.ScrollUpButton>
48
+ <SelectBase.Viewport className={style.viewport}>
49
+ {isGroupedOptions ? (
50
+ options.map((group, idx) => {
51
+ return (
52
+ <Fragment key={group.map(({ value }) => value).join("_")}>
53
+ {idx > 0 && (
54
+ <SelectBase.Separator className={style.separator} />
55
+ )}
56
+ <SelectGroup options={group} />
57
+ </Fragment>
58
+ );
59
+ })
60
+ ) : (
61
+ <SelectGroup options={options} />
62
+ )}
63
+ </SelectBase.Viewport>
64
+ <SelectBase.ScrollDownButton className={style.scrollButton}>
65
+ <ChevronDownIcon />
66
+ </SelectBase.ScrollDownButton>
67
+ </SelectBase.Content>
68
+ </SelectBase.Portal>
69
+ </SelectBase.Root>
70
+ );
71
+ }
@@ -0,0 +1,100 @@
1
+ @import "../style.module.scss";
2
+
3
+ :global(.sp-presenter-overlay) {
4
+ button.trigger {
5
+ @extend %item;
6
+ display: inline-flex;
7
+ align-items: center;
8
+ justify-content: space-between;
9
+ gap: 5px;
10
+ border-radius: 4px;
11
+ padding: 0 15px;
12
+ height: $item-height;
13
+ min-width: 120px;
14
+ background-color: var(--sp-toolbar-select-trigger);
15
+
16
+ &:hover {
17
+ @extend %hover;
18
+ }
19
+
20
+ &:focus {
21
+ @extend %focus;
22
+ }
23
+
24
+ &[data-placeholder] {
25
+ color: var(--sp-toolbar-highlight-color);
26
+ }
27
+
28
+ .icon {
29
+ color: var(--sp-toolbar-color);
30
+ }
31
+ }
32
+
33
+ .content {
34
+ @extend %root;
35
+ position: relative;
36
+ z-index: 10000;
37
+ max-height: var(--radix-select-content-available-height);
38
+
39
+ .group {
40
+ &:first-child {
41
+ .item:first-child {
42
+ padding-top: 8px;
43
+ }
44
+ }
45
+
46
+ &:last-child {
47
+ .item:last-child {
48
+ padding-bottom: 8px;
49
+ }
50
+ }
51
+ }
52
+
53
+ .item {
54
+ @extend %item-vertical;
55
+ position: relative;
56
+ display: flex;
57
+ align-items: center;
58
+ padding-right: 35px;
59
+ padding-left: 25px;
60
+ user-select: none;
61
+
62
+ &:hover,
63
+ &[data-highlighted] {
64
+ @extend %hover;
65
+ outline: 0;
66
+ }
67
+
68
+ &:focus {
69
+ @extend %focus;
70
+ }
71
+
72
+ &[data-disabled] {
73
+ @extend %disabled;
74
+ }
75
+ }
76
+
77
+ .item-indicator {
78
+ position: absolute;
79
+ left: 0;
80
+ width: 25px;
81
+ display: inline-flex;
82
+ align-items: center;
83
+ justify-content: center;
84
+ }
85
+
86
+ .scroll-button {
87
+ display: flex;
88
+ align-items: center;
89
+ justify-content: center;
90
+ height: 25px;
91
+ background-color: white;
92
+ color: var(--sp-toolbar-color);
93
+ cursor: default;
94
+ }
95
+ }
96
+
97
+ .separator {
98
+ @extend %separator-horizontal;
99
+ }
100
+ }
@@ -0,0 +1,37 @@
1
+ import React from "react";
2
+
3
+ import classNames from "classnames";
4
+ import { Select as SelectBase } from "radix-ui";
5
+
6
+ import { CheckIcon } from "@radix-ui/react-icons";
7
+
8
+ import style from "./Select.module.scss";
9
+
10
+ export function SelectGroup({ options = [] }) {
11
+ return (
12
+ <SelectBase.Group className={style.group}>
13
+ {options.map(({ label, value }, index) => (
14
+ <SelectItem key={`option-${index}`} value={value}>
15
+ {label}
16
+ </SelectItem>
17
+ ))}
18
+ </SelectBase.Group>
19
+ );
20
+ }
21
+
22
+ const SelectItem = React.forwardRef(
23
+ ({ children, className, ...props }, forwardedRef) => {
24
+ return (
25
+ <SelectBase.Item
26
+ className={classNames(style.item, className)}
27
+ {...props}
28
+ ref={forwardedRef}
29
+ >
30
+ <SelectBase.ItemText>{children}</SelectBase.ItemText>
31
+ <SelectBase.ItemIndicator className={style.itemIndicator}>
32
+ <CheckIcon />
33
+ </SelectBase.ItemIndicator>
34
+ </SelectBase.Item>
35
+ );
36
+ },
37
+ );
@@ -0,0 +1 @@
1
+ export { Select } from "./Select";
@@ -0,0 +1,43 @@
1
+ import React from "react";
2
+
3
+ import { useTransitions } from "@livepreso/content-react";
4
+
5
+ import { BubbleMenu } from "./BubbleMenu.js";
6
+ import { EditorMenu } from "./editor-toolbars/EditorMenu.js";
7
+ // import { ToolbarOptions } from "./ToolbarOptions.js";
8
+
9
+ export function TableCellMenu({
10
+ editor,
11
+ editorState,
12
+ userSelections,
13
+ configuration = [],
14
+ maskSelector,
15
+ }) {
16
+ const { exited } = useTransitions();
17
+
18
+ if (exited) {
19
+ return null;
20
+ }
21
+
22
+ return (
23
+ <BubbleMenu
24
+ editor={editor}
25
+ options={{
26
+ placement: "right-start",
27
+ offset: { mainAxis: -30, crossAxis: 4 },
28
+ closestSelector: "td, th",
29
+ maskSelector,
30
+ }}
31
+ shouldShow={({ editor }) => {
32
+ return editor.isFocused && editor.isActive("table");
33
+ }}
34
+ >
35
+ <EditorMenu
36
+ configuration={configuration}
37
+ editor={editor}
38
+ editorState={editorState}
39
+ userSelections={userSelections}
40
+ />
41
+ </BubbleMenu>
42
+ );
43
+ }