@monolith-forensics/monolith-ui 1.9.3-dev.4 → 2.0.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.
Files changed (33) hide show
  1. package/dist/Button/Button.js +11 -4
  2. package/dist/DropDownMenu/DropDownMenu.js +12 -2
  3. package/dist/DropDownMenu/components/MenuComponent.js +7 -1
  4. package/dist/DropDownMenu/components/MenuItem.js +4 -2
  5. package/dist/DropDownMenu/components/MenuItemList.d.ts +1 -0
  6. package/dist/DropDownMenu/components/MenuItemList.js +17 -7
  7. package/dist/DropDownMenu/components/SearchInput.js +2 -1
  8. package/dist/DropDownMenu/components/StyledContent.js +3 -2
  9. package/dist/DropDownMenu/constants.d.ts +4 -0
  10. package/dist/DropDownMenu/constants.js +4 -0
  11. package/dist/QueryFilter/DefaultOperators.d.ts +76 -0
  12. package/dist/QueryFilter/DefaultOperators.js +21 -0
  13. package/dist/QueryFilter/types.d.ts +66 -0
  14. package/dist/QueryFilter/types.js +1 -0
  15. package/dist/RichTextEditor/Enums/Controls.d.ts +1 -0
  16. package/dist/RichTextEditor/Enums/Controls.js +1 -0
  17. package/dist/RichTextEditor/Enums/Extensions.d.ts +1 -0
  18. package/dist/RichTextEditor/Enums/Extensions.js +1 -0
  19. package/dist/RichTextEditor/Enums/SlashCommands.d.ts +1 -0
  20. package/dist/RichTextEditor/Enums/SlashCommands.js +1 -0
  21. package/dist/RichTextEditor/Extensions/BubbleMenuExtension.d.ts +7 -0
  22. package/dist/RichTextEditor/Extensions/BubbleMenuExtension.js +157 -0
  23. package/dist/RichTextEditor/Extensions/getSlashCommand.js +10 -1
  24. package/dist/RichTextEditor/Extensions/getTiptapExtensions.js +15 -0
  25. package/dist/RichTextEditor/RichTextEditor.js +51 -27
  26. package/dist/RichTextEditor/Toolbar/Controls.d.ts +13 -0
  27. package/dist/RichTextEditor/Toolbar/Controls.js +142 -3
  28. package/dist/RichTextEditor/Toolbar/Labels.d.ts +1 -0
  29. package/dist/RichTextEditor/Toolbar/Labels.js +1 -0
  30. package/dist/RichTextEditor/Toolbar/Toolbar.js +28 -2
  31. package/dist/Table/Utils/resizeHandler.d.ts +3 -0
  32. package/dist/Table/Utils/resizeHandler.js +84 -0
  33. package/package.json +4 -1
@@ -46,14 +46,16 @@ const StyledButton = styled.button `
46
46
  return `0px ${getControlSizeTokens(size).buttonPaddingX}px`;
47
47
  }};
48
48
 
49
- color: ${({ theme, variant, color }) => {
49
+ color: ${({ theme, variant, color, selected }) => {
50
50
  var _a, _b;
51
- if (variant === "default")
52
- return theme.palette.text.primary;
53
51
  if (variant === "contained")
54
52
  return "white";
55
53
  if (variant === "filled")
56
54
  return "white";
55
+ if (selected)
56
+ return theme.palette.primary.main;
57
+ if (variant === "default")
58
+ return theme.palette.text.primary;
57
59
  if (color) {
58
60
  return (((_b = (_a = theme === null || theme === void 0 ? void 0 : theme.button) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b[color]) ||
59
61
  colors[color] ||
@@ -69,6 +71,9 @@ const StyledButton = styled.button `
69
71
  resolvedColor =
70
72
  ((_b = (_a = theme === null || theme === void 0 ? void 0 : theme.button) === null || _a === void 0 ? void 0 : _a.background) === null || _b === void 0 ? void 0 : _b[color]) || colors[color];
71
73
  }
74
+ if (selected && variant !== "contained" && variant !== "filled") {
75
+ return theme.palette.primary.main + "20";
76
+ }
72
77
  switch (variant) {
73
78
  case "default":
74
79
  return theme.button.background.default;
@@ -121,7 +126,9 @@ const StyledButton = styled.button `
121
126
 
122
127
  cursor: pointer;
123
128
 
124
- transition: background-color 0.2s, border 0.2s;
129
+ transition:
130
+ background-color 0.2s,
131
+ border 0.2s;
125
132
 
126
133
  .inner-span {
127
134
  display: flex;
@@ -1,9 +1,19 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
3
  import { Menu, MenuItemList, StyledInnerItemContainer } from "./components";
4
+ import { DEFAULT_DROPDOWN_MAX_HEIGHT } from "./constants";
5
+ const getNumericCssLength = (value) => {
6
+ if (typeof value === "number")
7
+ return value;
8
+ if (typeof value !== "string")
9
+ return undefined;
10
+ const pixelMatch = value.trim().match(/^(\d+(?:\.\d+)?)px$/);
11
+ return pixelMatch ? Number(pixelMatch[1]) : undefined;
12
+ };
4
13
  export const DropDownMenu = ({ data, children, defaultValue, value, variant, arrow, size, searchable, grouped, onAddNew, loading, onScroll, onScrollToTop, onScrollToBottom, onSearch, manualSearch, multiselect, enableSelectAll, enableSelectedOptionStyling, renderOption, dynamicOptionHeight, onItemSelect, onChange, buttonProps, TooltipContent, dropDownProps, query, disabled, }) => {
5
- var _a;
14
+ var _a, _b, _c, _d, _e, _f;
6
15
  const isObjectArray = (_a = Object.keys((data === null || data === void 0 ? void 0 : data[0]) || {})) === null || _a === void 0 ? void 0 : _a.includes("label");
16
+ const maxDropdownHeight = (_f = (_e = (_c = getNumericCssLength((_b = dropDownProps === null || dropDownProps === void 0 ? void 0 : dropDownProps.style) === null || _b === void 0 ? void 0 : _b.height)) !== null && _c !== void 0 ? _c : getNumericCssLength((_d = dropDownProps === null || dropDownProps === void 0 ? void 0 : dropDownProps.style) === null || _d === void 0 ? void 0 : _d.maxHeight)) !== null && _e !== void 0 ? _e : getNumericCssLength(dropDownProps === null || dropDownProps === void 0 ? void 0 : dropDownProps.maxDropdownHeight)) !== null && _f !== void 0 ? _f : DEFAULT_DROPDOWN_MAX_HEIGHT;
7
17
  const [internalSelected, setInternalSelected] = useState(defaultValue || []);
8
18
  const isControlled = value !== undefined;
9
19
  const selected = isControlled ? value || [] : internalSelected;
@@ -35,5 +45,5 @@ export const DropDownMenu = ({ data, children, defaultValue, value, variant, arr
35
45
  const handleScrollToBottom = (e) => {
36
46
  onScrollToBottom === null || onScrollToBottom === void 0 ? void 0 : onScrollToBottom(e);
37
47
  };
38
- return (_jsx(Menu, { label: children, disabled: disabled, arrow: arrow, buttonSize: size, variant: variant, multiselect: multiselect, buttonProps: buttonProps, onMenuClose: handleMenuClose, dropDownProps: dropDownProps, children: _jsxs(StyledInnerItemContainer, { children: [loading && _jsx("div", { children: "Loading..." }), !loading && (_jsx(MenuItemList, { menuItems: data, searchable: searchable, grouped: grouped, onAddNew: onAddNew, onSearch: onSearch, manualSearch: manualSearch, dynamicOptionHeight: dynamicOptionHeight, selected: selected, TooltipContent: TooltipContent, multiselect: multiselect, enableSelectAll: enableSelectAll, enableSelectedOptionStyling: enableSelectedOptionStyling, size: size, handleAddItem: handleAddItem, handleRemoveItem: handleRemoveItem, handleSetSelected: handleSetSelected, onItemSelect: onItemSelect, renderOption: renderOption, onScroll: onScroll, onScrollToTop: onScrollToTop, onScrollToBottom: handleScrollToBottom, query: query }))] }) }));
48
+ return (_jsx(Menu, { label: children, disabled: disabled, arrow: arrow, buttonSize: size, variant: variant, multiselect: multiselect, buttonProps: buttonProps, onMenuClose: handleMenuClose, dropDownProps: dropDownProps, children: _jsxs(StyledInnerItemContainer, { children: [loading && _jsx("div", { children: "Loading..." }), !loading && (_jsx(MenuItemList, { menuItems: data, searchable: searchable, grouped: grouped, onAddNew: onAddNew, onSearch: onSearch, manualSearch: manualSearch, dynamicOptionHeight: dynamicOptionHeight, maxDropdownHeight: maxDropdownHeight, selected: selected, TooltipContent: TooltipContent, multiselect: multiselect, enableSelectAll: enableSelectAll, enableSelectedOptionStyling: enableSelectedOptionStyling, size: size, handleAddItem: handleAddItem, handleRemoveItem: handleRemoveItem, handleSetSelected: handleSetSelected, onItemSelect: onItemSelect, renderOption: renderOption, onScroll: onScroll, onScrollToTop: onScrollToTop, onScrollToBottom: handleScrollToBottom, query: query }))] }) }));
39
49
  };
@@ -18,8 +18,14 @@ import { MenuContext } from "./MenuContext";
18
18
  import { StyledFloatContainer } from "./StyledFloatContainer";
19
19
  import { StyledContent } from "./StyledContent";
20
20
  import { MenuItem } from "./MenuItem";
21
+ import { DEFAULT_DROPDOWN_MAX_HEIGHT } from "../constants";
21
22
  export const MenuComponent = forwardRef((_a, forwardedRef) => {
22
23
  var { children, label, arrow, size, buttonSize, variant, buttonProps, buttonRender, multiselect, onMenuClose, dropDownProps, disabled } = _a, props = __rest(_a, ["children", "label", "arrow", "size", "buttonSize", "variant", "buttonProps", "buttonRender", "multiselect", "onMenuClose", "dropDownProps", "disabled"]);
24
+ const _b = dropDownProps || {}, { style: dropDownStyle } = _b, contentProps = __rest(_b, ["style"]);
25
+ const contentStyle = Object.assign({ height: "fit-content", maxHeight: (dropDownStyle === null || dropDownStyle === void 0 ? void 0 : dropDownStyle.maxHeight) ||
26
+ (dropDownStyle === null || dropDownStyle === void 0 ? void 0 : dropDownStyle.height) ||
27
+ (dropDownProps === null || dropDownProps === void 0 ? void 0 : dropDownProps.maxDropdownHeight) ||
28
+ DEFAULT_DROPDOWN_MAX_HEIGHT }, dropDownStyle);
23
29
  const [isOpen, setIsOpen] = useState(false);
24
30
  const [hasFocusInside, setHasFocusInside] = useState(false);
25
31
  const [activeIndex, setActiveIndex] = useState(null);
@@ -119,5 +125,5 @@ export const MenuComponent = forwardRef((_a, forwardedRef) => {
119
125
  getItemProps,
120
126
  setHasFocusInside,
121
127
  isOpen,
122
- }, children: _jsx(FloatingList, { elementsRef: elementsRef, labelsRef: labelsRef, children: isOpen && (_jsx(FloatingPortal, { children: _jsx(FloatingFocusManager, { context: context, modal: false, initialFocus: isNested ? -1 : 0, returnFocus: !isNested, children: _jsx(StyledFloatContainer, Object.assign({ ref: refs.setFloating, className: "Menu", style: floatingStyles }, getFloatingProps(), { children: _jsx(StyledContent, Object.assign({ className: "mfFloatingContent" }, dropDownProps, { children: children })) })) }) })) }) })] }));
128
+ }, children: _jsx(FloatingList, { elementsRef: elementsRef, labelsRef: labelsRef, children: isOpen && (_jsx(FloatingPortal, { children: _jsx(FloatingFocusManager, { context: context, modal: false, initialFocus: isNested ? -1 : 0, returnFocus: !isNested, children: _jsx(StyledFloatContainer, Object.assign({ ref: refs.setFloating, className: "Menu", style: floatingStyles }, getFloatingProps(), { children: _jsx(StyledContent, Object.assign({ className: "mfFloatingContent", style: contentStyle }, contentProps, { children: children })) })) }) })) }) })] }));
123
129
  });
@@ -26,7 +26,7 @@ export const MenuItem = styled(forwardRef((_a, forwardedRef) => {
26
26
  return (_jsx(Tooltip, { content: TooltipContent ? _jsx(TooltipContent, { data: itemData }) : null, side: "left", children: _jsx(Button, Object.assign({}, props, { ref: useMergeRefs([
27
27
  item.ref,
28
28
  forwardedRef,
29
- ]), type: "button", role: "menuitem", tabIndex: isActive ? 0 : -1, disabled: disabled, justify: "start", color: props.color }, menu.getItemProps({
29
+ ]), type: "button", role: "menuitem", tabIndex: isActive ? 0 : -1, disabled: disabled, justify: "start", color: props.color, selected: false }, menu.getItemProps({
30
30
  onClick(event) {
31
31
  var _a;
32
32
  (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, event);
@@ -49,7 +49,9 @@ export const MenuItem = styled(forwardRef((_a, forwardedRef) => {
49
49
  min-height: ${({ size = "sm" }) => `${getControlSizeTokens(size).menuRowHeight}px`};
50
50
  width: 100%;
51
51
  min-width: 100%;
52
- height: ${({ size = "sm", $dynamicHeight }) => $dynamicHeight ? "auto" : `${getControlSizeTokens(size).menuRowHeight}px`};
52
+ height: ${({ size = "sm", $dynamicHeight }) => $dynamicHeight
53
+ ? "auto"
54
+ : `${getControlSizeTokens(size).menuRowHeight}px`};
53
55
  box-sizing: border-box;
54
56
  position: relative;
55
57
  user-select: none;
@@ -24,5 +24,6 @@ export declare const MenuItemList: React.FC<{
24
24
  onScroll?: (e: Event) => void;
25
25
  onScrollToTop?: (e: Event) => void;
26
26
  onScrollToBottom?: (e: Event) => void;
27
+ maxDropdownHeight?: number;
27
28
  query?: DropDownMenuProps["query"];
28
29
  }>;
@@ -22,6 +22,7 @@ import { useInfiniteQuery } from "@tanstack/react-query";
22
22
  import { useDebouncedCallback } from "use-debounce";
23
23
  import { SearchInput } from "./SearchInput";
24
24
  import Loader from "../../Loader";
25
+ import { DEFAULT_DROPDOWN_MAX_HEIGHT, DROPDOWN_CONTENT_VERTICAL_PADDING, SEARCH_INPUT_MARGIN_BOTTOM, } from "../constants";
25
26
  const getItemKey = (item) => item && typeof item === "object" && "value" in item ? item.value : item;
26
27
  const filterMenuItems = (menuItems, searchValue) => {
27
28
  return menuItems.filter((item) => {
@@ -128,7 +129,7 @@ const MeasuredRow = ({ children, index, setItemSize, style }) => {
128
129
  }, [children, index, setItemSize]);
129
130
  return (_jsx("div", { style: Object.assign(Object.assign({}, style), { overflow: "visible" }), children: _jsx("div", { ref: rowRef, children: children }) }));
130
131
  };
131
- export const MenuItemList = ({ menuItems, searchable, onSearch, manualSearch, dynamicOptionHeight, selected, TooltipContent, multiselect, enableSelectAll, enableSelectedOptionStyling, grouped, onAddNew, size, handleAddItem, handleRemoveItem, handleSetSelected, onItemSelect, renderOption, onScroll, onScrollToTop, onScrollToBottom, query, }) => {
132
+ export const MenuItemList = ({ menuItems, searchable, onSearch, manualSearch, dynamicOptionHeight, selected, TooltipContent, multiselect, enableSelectAll, enableSelectedOptionStyling, grouped, onAddNew, size, handleAddItem, handleRemoveItem, handleSetSelected, onItemSelect, renderOption, onScroll, onScrollToTop, onScrollToBottom, maxDropdownHeight = DEFAULT_DROPDOWN_MAX_HEIGHT, query, }) => {
132
133
  const [searchValue, setSearchValue] = useState("");
133
134
  const _a = query !== null && query !== void 0 ? query : {}, { queryKey, queryFn, getNextPageParam, initialPageParam } = _a, rest = __rest(_a, ["queryKey", "queryFn", "getNextPageParam", "initialPageParam"]);
134
135
  const targetElm = useRef(null);
@@ -253,16 +254,25 @@ export const MenuItemList = ({ menuItems, searchable, onSearch, manualSearch, dy
253
254
  const getDynamicItemSize = (index) => {
254
255
  var _a;
255
256
  return itemSizeMap.current[index] ||
256
- (((_a = displayItems[index]) === null || _a === void 0 ? void 0 : _a._isGroupHeader) ? itemHeight : estimatedDynamicItemHeight);
257
+ (((_a = displayItems[index]) === null || _a === void 0 ? void 0 : _a._isGroupHeader)
258
+ ? itemHeight
259
+ : estimatedDynamicItemHeight);
257
260
  };
258
261
  const estimatedHeight = dynamicListEnabled
259
262
  ? displayItems.reduce((total, _, index) => total + getDynamicItemSize(index), 0)
260
263
  : itemCount * itemHeight;
261
- const height = viewPortDimensions.height
262
- ? viewPortDimensions.height
263
- : estimatedHeight < 200
264
- ? estimatedHeight
265
- : 200;
264
+ const searchHeight = searchable
265
+ ? sizeTokens.height + SEARCH_INPUT_MARGIN_BOTTOM
266
+ : 0;
267
+ const selectAllHeight = multiselect && enableSelectAll && selectableItems.length > 0
268
+ ? itemHeight
269
+ : 0;
270
+ const maxListHeight = Math.max(itemHeight, maxDropdownHeight -
271
+ DROPDOWN_CONTENT_VERTICAL_PADDING -
272
+ searchHeight -
273
+ selectAllHeight);
274
+ const availableHeight = viewPortDimensions.height || maxListHeight;
275
+ const height = Math.min(estimatedHeight, availableHeight, maxListHeight);
266
276
  const width = "100%";
267
277
  useLayoutEffect(() => {
268
278
  const target = targetElm.current;
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import Input from "../../Input";
4
- export const SearchInput = forwardRef((props, ref) => _jsx(Input, Object.assign({ ref: ref, style: { marginBottom: 8 } }, props)));
4
+ import { SEARCH_INPUT_MARGIN_BOTTOM } from "../constants";
5
+ export const SearchInput = forwardRef((props, ref) => (_jsx(Input, Object.assign({ ref: ref, style: { marginBottom: SEARCH_INPUT_MARGIN_BOTTOM } }, props))));
@@ -1,4 +1,5 @@
1
1
  import styled from "styled-components";
2
+ import { DEFAULT_DROPDOWN_MAX_HEIGHT, DROPDOWN_CONTENT_PADDING, } from "../constants";
2
3
  export const StyledContent = styled.div `
3
4
  position: relative;
4
5
  display: flex;
@@ -11,7 +12,7 @@ export const StyledContent = styled.div `
11
12
  max-width: 400px;
12
13
  max-height: ${({ maxDropdownHeight }) => Number.isInteger(maxDropdownHeight)
13
14
  ? `${maxDropdownHeight}px`
14
- : maxDropdownHeight || "250px"};
15
+ : maxDropdownHeight || `${DEFAULT_DROPDOWN_MAX_HEIGHT}px`};
15
16
 
16
17
  background-color: ${(props) => props.theme.palette.background.default};
17
18
  background-color: ${({ theme, variant }) => {
@@ -30,7 +31,7 @@ export const StyledContent = styled.div `
30
31
  border-radius: 5px;
31
32
  border: 1px solid ${(props) => props.theme.palette.divider};
32
33
  outline: none;
33
- padding: 5px;
34
+ padding: ${DROPDOWN_CONTENT_PADDING}px;
34
35
  animation-duration: 400ms;
35
36
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
36
37
  will-change: transform, opacity;
@@ -0,0 +1,4 @@
1
+ export declare const DEFAULT_DROPDOWN_MAX_HEIGHT = 250;
2
+ export declare const DROPDOWN_CONTENT_PADDING = 5;
3
+ export declare const DROPDOWN_CONTENT_VERTICAL_PADDING: number;
4
+ export declare const SEARCH_INPUT_MARGIN_BOTTOM = 8;
@@ -0,0 +1,4 @@
1
+ export const DEFAULT_DROPDOWN_MAX_HEIGHT = 250;
2
+ export const DROPDOWN_CONTENT_PADDING = 5;
3
+ export const DROPDOWN_CONTENT_VERTICAL_PADDING = DROPDOWN_CONTENT_PADDING * 2;
4
+ export const SEARCH_INPUT_MARGIN_BOTTOM = 8;
@@ -0,0 +1,76 @@
1
+ import { Operator } from "./types";
2
+ export declare const Operators: {
3
+ Equals: {
4
+ value: string;
5
+ label: string;
6
+ };
7
+ NotEquals: {
8
+ value: string;
9
+ label: string;
10
+ };
11
+ LessThan: {
12
+ value: string;
13
+ label: string;
14
+ };
15
+ GreaterThan: {
16
+ value: string;
17
+ label: string;
18
+ };
19
+ LessThanOrEqual: {
20
+ value: string;
21
+ label: string;
22
+ };
23
+ GreaterThanOrEqual: {
24
+ value: string;
25
+ label: string;
26
+ };
27
+ Contains: {
28
+ value: string;
29
+ label: string;
30
+ };
31
+ BeginsWith: {
32
+ value: string;
33
+ label: string;
34
+ };
35
+ EndsWith: {
36
+ value: string;
37
+ label: string;
38
+ };
39
+ DoesNotContain: {
40
+ value: string;
41
+ label: string;
42
+ };
43
+ DoesNotBeginWith: {
44
+ value: string;
45
+ label: string;
46
+ };
47
+ DoesNotEndWith: {
48
+ value: string;
49
+ label: string;
50
+ };
51
+ IsEmpty: {
52
+ value: string;
53
+ label: string;
54
+ };
55
+ IsNotEmpty: {
56
+ value: string;
57
+ label: string;
58
+ };
59
+ In: {
60
+ value: string;
61
+ label: string;
62
+ };
63
+ NIn: {
64
+ value: string;
65
+ label: string;
66
+ };
67
+ Between: {
68
+ value: string;
69
+ label: string;
70
+ };
71
+ NotBetween: {
72
+ value: string;
73
+ label: string;
74
+ };
75
+ };
76
+ export declare const DefaultOperators: Operator[];
@@ -0,0 +1,21 @@
1
+ export const Operators = {
2
+ Equals: { value: "=", label: "is" },
3
+ NotEquals: { value: "!=", label: "is not" },
4
+ LessThan: { value: "<", label: "less than" },
5
+ GreaterThan: { value: ">", label: "greater than" },
6
+ LessThanOrEqual: { value: "<=", label: "less than or equal" },
7
+ GreaterThanOrEqual: { value: ">=", label: "greater than or equal" },
8
+ Contains: { value: "contains", label: "contains" },
9
+ BeginsWith: { value: "beginsWith", label: "begins with" },
10
+ EndsWith: { value: "endsWith", label: "ends with" },
11
+ DoesNotContain: { value: "doesNotContain", label: "does not contain" },
12
+ DoesNotBeginWith: { value: "doesNotBeginWith", label: "does not begin with" },
13
+ DoesNotEndWith: { value: "doesNotEndWith", label: "does not end with" },
14
+ IsEmpty: { value: "isEmpty", label: "is empty" },
15
+ IsNotEmpty: { value: "isNotEmpty", label: "is not empty" },
16
+ In: { value: "in", label: "is any of" },
17
+ NIn: { value: "nin", label: "is none of" },
18
+ Between: { value: "between", label: "between" },
19
+ NotBetween: { value: "notBetween", label: "not between" },
20
+ };
21
+ export const DefaultOperators = Object.values(Operators);
@@ -0,0 +1,66 @@
1
+ import { DropDownItem, DropDownMenuProps } from "../DropDownMenu";
2
+ export interface UseQueryFilterProps {
3
+ defaultFilter?: Query | null;
4
+ /**
5
+ * Filter definitions for the available fields. Pass `undefined` while the
6
+ * definitions are still loading (e.g. async fetch in flight) — any rules
7
+ * already in state will render nothing until definitions resolve. An empty
8
+ * array means "loaded, no definitions": every rule will render as an
9
+ * orphan chip and `onUnknownField` will fire for each.
10
+ */
11
+ filterDefinitions: FilterDefinition[] | undefined;
12
+ showCombinator?: boolean;
13
+ onFilterChange?: (filter: any) => void;
14
+ onUnknownField?: (rule: Rule) => void;
15
+ }
16
+ export type QueryFilterType = {
17
+ filter: Query;
18
+ filterDefinitions: FilterDefinition[] | undefined;
19
+ showCombinator?: boolean;
20
+ addRule: (rule: Rule) => void;
21
+ /**
22
+ * Remove a rule by `id` (preferred) or by passing the `Rule` object. The
23
+ * object form falls back to reference equality when `rule.id` is missing,
24
+ * so chips for un-normalized orphan rules can still delete themselves.
25
+ */
26
+ removeRule: (target: string | Rule) => void;
27
+ updateRule: (rule: Rule) => void;
28
+ updateRootCombinator: (combinator: Combinator) => void;
29
+ onUnknownField?: (rule: Rule) => void;
30
+ };
31
+ export type UseQueryFilter = (args: UseQueryFilterProps) => QueryFilterType;
32
+ export type Combinator = "and" | "or";
33
+ export type Operator = {
34
+ label: string;
35
+ value: string;
36
+ };
37
+ export type InputType = "text" | "number" | "date" | "datetime" | "multiselect";
38
+ export interface FilterDefinition {
39
+ dataField: string;
40
+ label: string;
41
+ pluralLabel?: string;
42
+ operators?: Operator[];
43
+ inputType?: InputType;
44
+ resolution?: "day" | "second" | "millisecond";
45
+ isoString?: boolean;
46
+ placeholder?: string;
47
+ selectOptions?: DropDownItem[];
48
+ dropDownOptions?: {
49
+ style?: React.CSSProperties;
50
+ };
51
+ query?: DropDownMenuProps["query"];
52
+ }
53
+ export interface Rule {
54
+ id?: string;
55
+ dataField: string;
56
+ value?: string[];
57
+ options?: DropDownItem[];
58
+ operator: Operator;
59
+ label: string;
60
+ }
61
+ export interface RuleGroup {
62
+ rules: Rule[];
63
+ combinator: Combinator;
64
+ }
65
+ export interface Query extends RuleGroup {
66
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -16,6 +16,7 @@ export declare enum Controls {
16
16
  HEADING_4 = "heading_4",
17
17
  BULLET_LIST = "bulletList",
18
18
  ORDERED_LIST = "orderedList",
19
+ TASK_LIST = "taskList",
19
20
  TEXT_ALIGN_LEFT = "textAlignLeft",
20
21
  TEXT_ALIGN_CENTER = "textAlignCenter",
21
22
  TEXT_ALIGN_RIGHT = "textAlignRight",
@@ -17,6 +17,7 @@ export var Controls;
17
17
  Controls["HEADING_4"] = "heading_4";
18
18
  Controls["BULLET_LIST"] = "bulletList";
19
19
  Controls["ORDERED_LIST"] = "orderedList";
20
+ Controls["TASK_LIST"] = "taskList";
20
21
  Controls["TEXT_ALIGN_LEFT"] = "textAlignLeft";
21
22
  Controls["TEXT_ALIGN_CENTER"] = "textAlignCenter";
22
23
  Controls["TEXT_ALIGN_RIGHT"] = "textAlignRight";
@@ -14,6 +14,7 @@ export declare enum Extensions {
14
14
  Strike = "strike",
15
15
  BulletList = "bulletList",
16
16
  OrderedList = "orderedList",
17
+ TaskList = "taskList",
17
18
  AlignLeft = "alignLeft",
18
19
  AlignCenter = "alignCenter",
19
20
  AlignRight = "alignRight",
@@ -15,6 +15,7 @@ export var Extensions;
15
15
  Extensions["Strike"] = "strike";
16
16
  Extensions["BulletList"] = "bulletList";
17
17
  Extensions["OrderedList"] = "orderedList";
18
+ Extensions["TaskList"] = "taskList";
18
19
  Extensions["AlignLeft"] = "alignLeft";
19
20
  Extensions["AlignCenter"] = "alignCenter";
20
21
  Extensions["AlignRight"] = "alignRight";
@@ -6,6 +6,7 @@ export declare enum SlashCommands {
6
6
  Heading4 = "Heading 4",
7
7
  BulletList = "Bullet List",
8
8
  NumberedList = "Numbered List",
9
+ TaskList = "Task List",
9
10
  Code = "Code",
10
11
  CodeBlock = "Code Block",
11
12
  HorizontalRule = "Horizontal Rule",
@@ -7,6 +7,7 @@ export var SlashCommands;
7
7
  SlashCommands["Heading4"] = "Heading 4";
8
8
  SlashCommands["BulletList"] = "Bullet List";
9
9
  SlashCommands["NumberedList"] = "Numbered List";
10
+ SlashCommands["TaskList"] = "Task List";
10
11
  SlashCommands["Code"] = "Code";
11
12
  SlashCommands["CodeBlock"] = "Code Block";
12
13
  SlashCommands["HorizontalRule"] = "Horizontal Rule";
@@ -0,0 +1,7 @@
1
+ import { Extension } from "@tiptap/core";
2
+ import { BubbleItem } from "../Components/BubbleMenu";
3
+ export type BubbleMenuOptions = {
4
+ customMenuItems?: BubbleItem[];
5
+ };
6
+ declare const BubbleMenu: Extension<any, any>;
7
+ export default BubbleMenu;
@@ -0,0 +1,157 @@
1
+ import { Extension, isNodeSelection, isTextSelection, posToDOMRect, } from "@tiptap/core";
2
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
3
+ import { ReactRenderer } from "@tiptap/react";
4
+ import BubbleMenuComponent from "../Components/BubbleMenu";
5
+ class Menu {
6
+ constructor({ view, editor, customMenuItems, }) {
7
+ this.mousedownHandler = (event) => {
8
+ this.preventShow = true;
9
+ };
10
+ this.mouseUpHandler = (event) => {
11
+ this.preventShow = false;
12
+ this.update(this.editor.view);
13
+ };
14
+ this.focusHandler = () => {
15
+ // this.editor.commands.setTextSelection({ from: 0, to: 0 });
16
+ // we use `setTimeout` to make sure `selection` is already updated
17
+ setTimeout(() => this.update(this.editor.view));
18
+ };
19
+ this.blurHandler = ({ event }) => {
20
+ var _a;
21
+ if (this.preventShow) {
22
+ this.preventShow = false;
23
+ return;
24
+ }
25
+ if ((event === null || event === void 0 ? void 0 : event.relatedTarget) &&
26
+ ((_a = this.floating) === null || _a === void 0 ? void 0 : _a.contains(event === null || event === void 0 ? void 0 : event.relatedTarget))) {
27
+ return;
28
+ }
29
+ // clear text selection
30
+ // this.editor.commands.setTextSelection({ from: 0, to: 0 });
31
+ this.hide();
32
+ };
33
+ this.editor = editor;
34
+ this.view = view;
35
+ this.rect = null;
36
+ this.preventShow = false;
37
+ this.floating = null;
38
+ this.isOpen = false;
39
+ // create and mount react component
40
+ if (!this.component) {
41
+ this.component = new ReactRenderer(BubbleMenuComponent, {
42
+ props: {
43
+ editor: this.editor,
44
+ open: false,
45
+ onOpen: (ref) => {
46
+ this.floating = ref;
47
+ },
48
+ customMenuItems,
49
+ },
50
+ editor: this.editor,
51
+ });
52
+ document.body.appendChild(this.component.element);
53
+ }
54
+ // don't show the bubble during selection of text
55
+ this.view.dom.addEventListener("mousedown", this.mousedownHandler, {
56
+ capture: true,
57
+ });
58
+ this.view.dom.addEventListener("mouseup", this.mouseUpHandler);
59
+ this.editor.on("blur", this.blurHandler);
60
+ this.editor.on("focus", this.focusHandler);
61
+ }
62
+ update(view, oldState) {
63
+ var _a;
64
+ const { state, composing } = view;
65
+ const { doc, selection } = state;
66
+ const { empty, ranges } = selection;
67
+ const from = Math.min(...ranges.map((range) => range.$from.pos));
68
+ const to = Math.max(...ranges.map((range) => range.$to.pos));
69
+ const selectionChanged = !(oldState === null || oldState === void 0 ? void 0 : oldState.selection.eq(view.state.selection));
70
+ const docChanged = !(oldState === null || oldState === void 0 ? void 0 : oldState.doc.eq(view.state.doc));
71
+ const isSame = !selectionChanged && !docChanged;
72
+ if (composing || isSame) {
73
+ return;
74
+ }
75
+ // Sometime check for `empty` is not enough.
76
+ // Doubleclick an empty paragraph returns a node size of 2.
77
+ // So we check also for an empty text size.
78
+ const isEmptyTextBlock = !doc.textBetween(from, to).length && isTextSelection(state.selection);
79
+ // When clicking on a element inside the bubble menu the editor "blur" event
80
+ // is called and the bubble menu item is focussed. In this case we should
81
+ // consider the menu as part of the editor and keep showing the menu
82
+ const isChildOfMenu = (_a = this === null || this === void 0 ? void 0 : this.floating) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);
83
+ const hasEditorFocus = view.hasFocus() || isChildOfMenu;
84
+ if (!hasEditorFocus ||
85
+ empty ||
86
+ isEmptyTextBlock ||
87
+ !this.editor.isEditable ||
88
+ this.preventShow) {
89
+ this.hide();
90
+ }
91
+ else {
92
+ // only set position when it is not already open
93
+ // otherwise the menu will jump around when the selection changes or text formatting is applied
94
+ if (!this.isOpen) {
95
+ if (isNodeSelection(state.selection)) {
96
+ let node = view.nodeDOM(from);
97
+ const nodeViewWrapper = node.dataset.nodeViewWrapper
98
+ ? node
99
+ : node.querySelector("[data-node-view-wrapper]");
100
+ if (nodeViewWrapper) {
101
+ node = nodeViewWrapper.firstChild;
102
+ }
103
+ if (node) {
104
+ this.rect = node.getBoundingClientRect();
105
+ }
106
+ }
107
+ else {
108
+ this.rect = posToDOMRect(view, from, to);
109
+ }
110
+ }
111
+ this.show();
112
+ }
113
+ }
114
+ show() {
115
+ if (this.component) {
116
+ this.component.updateProps({ open: true, rect: this.rect });
117
+ this.isOpen = true;
118
+ }
119
+ }
120
+ hide() {
121
+ if (this.component) {
122
+ this.component.updateProps({ open: false, rect: null });
123
+ this.isOpen = false;
124
+ }
125
+ }
126
+ destroy() {
127
+ if (this.component) {
128
+ this.view.dom.removeEventListener("mousedown", this.mousedownHandler);
129
+ this.view.dom.removeEventListener("mouseup", this.mouseUpHandler);
130
+ this.component.destroy();
131
+ }
132
+ }
133
+ }
134
+ const BubbleMenu = Extension.create({
135
+ name: "bubbleMenu",
136
+ addOptions() {
137
+ return {
138
+ bubbleMenuOptions: {},
139
+ };
140
+ },
141
+ addProseMirrorPlugins() {
142
+ return [
143
+ new Plugin({
144
+ key: new PluginKey("bubbleMenu"),
145
+ view: (view) => {
146
+ var _a;
147
+ return new Menu({
148
+ view,
149
+ editor: this.editor,
150
+ customMenuItems: ((_a = this === null || this === void 0 ? void 0 : this.options) === null || _a === void 0 ? void 0 : _a.customMenuItems) || [],
151
+ });
152
+ },
153
+ }),
154
+ ];
155
+ },
156
+ });
157
+ export default BubbleMenu;
@@ -11,7 +11,7 @@ import { Extension } from "@tiptap/core";
11
11
  import Suggestion from "@tiptap/suggestion";
12
12
  import { ReactRenderer } from "@tiptap/react";
13
13
  import tippy from "tippy.js";
14
- import { Heading1, Heading2, Heading3, Heading4, List, ListOrdered, Text, TextQuote, Image as ImageIcon, Calendar, CodeIcon, ClockIcon, SeparatorHorizontalIcon, SquareCodeIcon, Table2Icon, } from "lucide-react";
14
+ import { Heading1, Heading2, Heading3, Heading4, List, ListOrdered, Text, TextQuote, Image as ImageIcon, Calendar, CodeIcon, ClockIcon, ListChecksIcon, SeparatorHorizontalIcon, SquareCodeIcon, Table2Icon, } from "lucide-react";
15
15
  import { startImageUpload, } from "../Plugins/UploadImagesPlugin.js";
16
16
  import { PluginKey } from "@tiptap/pm/state";
17
17
  import SlashCommandList from "./SlashCommandList";
@@ -116,6 +116,15 @@ const getCommandItems = (values, options) => {
116
116
  editor.chain().focus().deleteRange(range).toggleOrderedList().run();
117
117
  },
118
118
  },
119
+ {
120
+ title: SlashCommands.TaskList,
121
+ description: "Create a checklist with tasks.",
122
+ searchTerms: ["todo", "checklist", "checkbox"],
123
+ icon: ListChecksIcon,
124
+ command: ({ editor, range }) => {
125
+ editor.chain().focus().deleteRange(range).toggleTaskList().run();
126
+ },
127
+ },
119
128
  {
120
129
  title: SlashCommands.Code,
121
130
  description: "Start typing inline code.",
@@ -4,6 +4,8 @@ import { CodeBlockLowlight } from "@tiptap/extension-code-block-lowlight";
4
4
  import HorizontalRule from "@tiptap/extension-horizontal-rule";
5
5
  import TextAlign from "@tiptap/extension-text-align";
6
6
  import { Table, TableCell, TableHeader, TableRow, } from "@tiptap/extension-table";
7
+ import TaskList from "@tiptap/extension-task-list";
8
+ import TaskItem from "@tiptap/extension-task-item";
7
9
  import { Focus, Placeholder } from "@tiptap/extensions";
8
10
  import { Color } from "@tiptap/extension-color";
9
11
  import { Highlight } from "@tiptap/extension-highlight";
@@ -89,6 +91,7 @@ export const MINIMAL_EXTENSIONS = [
89
91
  export const FULL_EXTENSIONS = [
90
92
  ...BASIC_EXTENSIONS,
91
93
  Extensions.CodeBlock,
94
+ Extensions.TaskList,
92
95
  Extensions.Table,
93
96
  Extensions.TableCell,
94
97
  Extensions.TableHeader,
@@ -269,6 +272,16 @@ const getTipTapExtensions = ({ disabledExtensions = [], extensions = [], slashCo
269
272
  name: Extensions.TableCell,
270
273
  extension: TableCell,
271
274
  },
275
+ {
276
+ name: Extensions.TaskList,
277
+ extension: TaskList,
278
+ },
279
+ {
280
+ name: "taskItem",
281
+ extension: TaskItem.configure({
282
+ nested: true,
283
+ }),
284
+ },
272
285
  {
273
286
  name: Extensions.Image,
274
287
  extension: CustomImage.configure({
@@ -314,6 +327,8 @@ const getTipTapExtensions = ({ disabledExtensions = [], extensions = [], slashCo
314
327
  .filter((ext) => {
315
328
  if (ext.name === "starterKit")
316
329
  return true;
330
+ if (ext.name === "taskItem")
331
+ return isEnabled(Extensions.TaskList);
317
332
  return isEnabled(ext.name);
318
333
  })
319
334
  .map((ext) => ext.extension);
@@ -26,6 +26,7 @@ import Fonts from "./Enums/Fonts";
26
26
  import RichTextEditorContext from "./Contexts/RichTextEditorContext";
27
27
  import { getLinkAttributesAtPosition, getLinkRangeAtPosition, openLink, } from "./Utils/linkUtils";
28
28
  import { TABLE_CELL_MIN_WIDTH } from "./Utils/tableUtils";
29
+ import { getControlSizeTokens } from "../core";
29
30
  const codeBlockFallbacks = {
30
31
  light: {
31
32
  background: "#f6f8fa",
@@ -74,6 +75,7 @@ const codeBlockFallbacks = {
74
75
  },
75
76
  },
76
77
  };
78
+ const TASK_CHECKBOX_SIZE = getControlSizeTokens("sm").checkboxIconSize;
77
79
  const getCodeBlockTheme = (theme) => {
78
80
  if (theme.palette.codeBlock)
79
81
  return theme.palette.codeBlock;
@@ -758,59 +760,77 @@ const StyledContent = styled.div `
758
760
 
759
761
  ul[data-type="taskList"] {
760
762
  list-style: none;
763
+ margin: 0.25rem 0;
761
764
  padding: 0;
762
765
 
763
766
  li {
764
767
  display: flex;
765
- align-items: center;
768
+ align-items: flex-start;
766
769
  margin: 0.25rem 0;
767
770
 
768
771
  > label {
772
+ display: inline-flex;
773
+ align-items: center;
774
+ justify-content: center;
769
775
  flex: 0 0 auto;
776
+ height: 1.5rem;
770
777
  margin-right: 0.5rem;
771
778
  user-select: none;
772
779
  }
773
780
 
774
781
  > div {
775
782
  flex: 1 1 auto;
783
+ min-width: 0;
784
+ }
785
+
786
+ > div > ul[data-type="taskList"] {
787
+ margin: 0.25rem 0 0;
776
788
  }
777
789
  }
778
790
 
779
791
  input[type="checkbox"] {
780
- cursor: pointer;
781
- margin: 0;
782
792
  -webkit-appearance: none;
783
793
  appearance: none;
784
- border: 2px solid ${({ theme }) => theme.palette.primary.main};
785
- border-radius: 0.125rem;
786
- background-color: ${({ theme }) => theme.palette.background.default};
787
- width: 1.25rem;
788
- height: 1.25rem;
789
- display: grid;
790
- place-content: center;
791
-
792
- &:hover {
793
- border-color: ${({ theme }) => theme.palette.primary.main};
794
+ position: relative;
795
+ display: inline-flex;
796
+ align-items: center;
797
+ justify-content: center;
798
+ box-sizing: border-box;
799
+ width: ${TASK_CHECKBOX_SIZE}px;
800
+ height: ${TASK_CHECKBOX_SIZE}px;
801
+ margin: 0;
802
+ border: 1px solid ${({ theme }) => theme.palette.text.secondary};
803
+ border-radius: 2px;
804
+ background-color: transparent;
805
+ cursor: pointer;
806
+
807
+ &::after {
808
+ content: "";
809
+ position: absolute;
810
+ left: 50%;
811
+ top: 45%;
812
+ width: 32%;
813
+ height: 56%;
814
+ border: solid
815
+ ${({ theme }) => (theme.name === "DARK" ? "#000000" : "#ffffff")};
816
+ border-width: 0 2px 2px 0;
817
+ opacity: 0;
818
+ transform: translate(-50%, -50%) rotate(45deg);
819
+ transform-origin: center;
794
820
  }
795
821
 
796
- &:active {
797
- background-color: ${({ theme }) => theme.palette.divider};
822
+ &:checked {
823
+ background-color: ${({ theme }) => theme.name === "DARK" ? "#cdcdcd" : "#646464"};
824
+ border-color: ${({ theme }) => theme.name === "DARK" ? "#cdcdcd" : "#646464"};
798
825
  }
799
826
 
800
- &::before {
801
- content: "";
802
- width: 0.75em;
803
- height: 0.75em;
804
- transform: scale(0);
805
- transition: 120ms transform ease-in-out;
806
- box-shadow: inset 1em 1em;
807
- transform-origin: center;
808
- clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
809
- color: ${({ theme }) => theme.palette.text.primary};
827
+ &:checked::after {
828
+ opacity: 1;
810
829
  }
811
830
 
812
- &:checked::before {
813
- transform: scale(1);
831
+ &:focus-visible {
832
+ outline: 2px solid ${({ theme }) => theme.palette.primary.main}40;
833
+ outline-offset: 2px;
814
834
  }
815
835
  }
816
836
  }
@@ -856,6 +876,9 @@ export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = ""
856
876
  if (command === SlashCommands.Table) {
857
877
  return resolvedExtensionSet.has(Extensions.Table);
858
878
  }
879
+ if (command === SlashCommands.TaskList) {
880
+ return resolvedExtensionSet.has(Extensions.TaskList);
881
+ }
859
882
  return true;
860
883
  }), [resolvedExtensionSet, slashCommands]);
861
884
  const resolvedToolbarOptions = useMemo(() => {
@@ -872,6 +895,7 @@ export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = ""
872
895
  [Controls.HORIZONTAL_RULE]: Extensions.HorizontalRule,
873
896
  [Controls.BULLET_LIST]: Extensions.BulletList,
874
897
  [Controls.ORDERED_LIST]: Extensions.OrderedList,
898
+ [Controls.TASK_LIST]: Extensions.TaskList,
875
899
  [Controls.COLOR]: Extensions.Color,
876
900
  [Controls.HIGHLIGHT]: Extensions.Highlight,
877
901
  [Controls.LINK]: Extensions.Link,
@@ -2,6 +2,9 @@ import { Editor } from "@tiptap/react";
2
2
  interface ControlProps {
3
3
  editor: Editor | null;
4
4
  }
5
+ export type HeadingLevel = 1 | 2 | 3 | 4;
6
+ export type TextAlignment = "left" | "center" | "right" | "justify";
7
+ export type ListType = "bullet" | "ordered" | "task";
5
8
  export declare const UndoControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
6
9
  export declare const RedoControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
7
10
  export declare const FontControl: () => import("react/jsx-runtime").JSX.Element;
@@ -20,10 +23,20 @@ export declare const Heading1Control: ({ editor }: ControlProps) => import("reac
20
23
  export declare const Heading2Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
21
24
  export declare const Heading3Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
22
25
  export declare const Heading4Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
26
+ export declare const HeadingControl: ({ editor, levels, }: ControlProps & {
27
+ levels?: HeadingLevel[];
28
+ }) => import("react/jsx-runtime").JSX.Element | null;
23
29
  export declare const BulletListControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
24
30
  export declare const OrderedListControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
31
+ export declare const TaskListControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
32
+ export declare const ListControl: ({ editor, listTypes, }: ControlProps & {
33
+ listTypes?: ListType[];
34
+ }) => import("react/jsx-runtime").JSX.Element | null;
25
35
  export declare const AlignLeftControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
26
36
  export declare const AlignRightControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
27
37
  export declare const AlignCenterControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
28
38
  export declare const AlignJustifiedControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
39
+ export declare const AlignmentControl: ({ editor, alignments, }: ControlProps & {
40
+ alignments?: TextAlignment[];
41
+ }) => import("react/jsx-runtime").JSX.Element | null;
29
42
  export {};
@@ -1,7 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { IconBold, IconItalic, IconUnderline, IconStrikethrough, IconH1, IconH2, IconH3, IconH4, IconList, IconListNumbers, IconAlignLeft, IconAlignRight, IconAlignCenter, IconAlignJustified, IconCornerUpLeft, IconCornerUpRight, IconBlockquote, IconSeparatorHorizontal, } from "@tabler/icons-react";
3
- import { CodeIcon, HighlighterIcon, PaletteIcon, RemoveFormattingIcon, SquircleIcon, TypeIcon, } from "lucide-react";
4
- import { SquareCodeIcon } from "lucide-react";
2
+ import { IconBold, IconItalic, IconUnderline, IconStrikethrough, IconH1, IconH2, IconH3, IconH4, IconHeading, IconList, IconListNumbers, IconAlignLeft, IconAlignRight, IconAlignCenter, IconAlignJustified, IconCornerUpLeft, IconCornerUpRight, IconBlockquote, IconSeparatorHorizontal, } from "@tabler/icons-react";
3
+ import { CodeIcon, HighlighterIcon, ListChecksIcon, PaletteIcon, RemoveFormattingIcon, SquareCodeIcon, SquircleIcon, TypeIcon, } from "lucide-react";
5
4
  import { Control } from "./Control";
6
5
  import { hasInlineCode, toggleInlineCode } from "../Utils/codeUtils";
7
6
  import { hasSyntaxHighlightedCodeBlock, toggleCodeBlock, } from "../Utils/codeBlockUtils";
@@ -12,6 +11,38 @@ import RichTextEditorContext from "../Contexts/RichTextEditorContext";
12
11
  import Fonts from "../Enums/Fonts";
13
12
  import TextColors from "../Enums/TextColors";
14
13
  import HighlightColors from "../Enums/HighlightColors";
14
+ const headingControlOptions = [
15
+ { level: 1, label: "Heading 1", icon: IconH1 },
16
+ { level: 2, label: "Heading 2", icon: IconH2 },
17
+ { level: 3, label: "Heading 3", icon: IconH3 },
18
+ { level: 4, label: "Heading 4", icon: IconH4 },
19
+ ];
20
+ const alignmentControlOptions = [
21
+ { value: "left", label: "Align text: left", icon: IconAlignLeft },
22
+ { value: "center", label: "Align text: center", icon: IconAlignCenter },
23
+ { value: "right", label: "Align text: right", icon: IconAlignRight },
24
+ { value: "justify", label: "Align text: justify", icon: IconAlignJustified },
25
+ ];
26
+ const listControlOptions = [
27
+ {
28
+ value: "bullet",
29
+ label: "Bullet list",
30
+ nodeName: "bulletList",
31
+ icon: IconList,
32
+ },
33
+ {
34
+ value: "ordered",
35
+ label: "Ordered list",
36
+ nodeName: "orderedList",
37
+ icon: IconListNumbers,
38
+ },
39
+ {
40
+ value: "task",
41
+ label: "Task list",
42
+ nodeName: "taskList",
43
+ icon: ListChecksIcon,
44
+ },
45
+ ];
15
46
  export const UndoControl = ({ editor }) => {
16
47
  return (_jsx(Control, { editor: editor, label: "undoControlLabel", operation: {
17
48
  name: "undo",
@@ -204,6 +235,37 @@ export const Heading4Control = ({ editor }) => {
204
235
  attributes: { level: 4 },
205
236
  }, icon: IconH4 }));
206
237
  };
238
+ export const HeadingControl = ({ editor, levels = [1, 2, 3, 4], }) => {
239
+ const options = headingControlOptions.filter((option) => levels.includes(option.level));
240
+ const currentHeading = headingControlOptions.find((option) => editor === null || editor === void 0 ? void 0 : editor.isActive("heading", { level: option.level }));
241
+ const selectedHeading = options.find((option) => option.level === (currentHeading === null || currentHeading === void 0 ? void 0 : currentHeading.level));
242
+ const ButtonIcon = (currentHeading === null || currentHeading === void 0 ? void 0 : currentHeading.icon) || IconHeading;
243
+ if (!options.length)
244
+ return null;
245
+ return (_jsx(DropDownMenu, { data: options.map((option) => ({
246
+ label: option.label,
247
+ value: option.level,
248
+ onClick: () => {
249
+ editor === null || editor === void 0 ? void 0 : editor.chain().focus().toggleHeading({ level: option.level }).run();
250
+ },
251
+ })), value: selectedHeading
252
+ ? [{ label: selectedHeading.label, value: selectedHeading.level }]
253
+ : [], enableSelectedOptionStyling: true, renderOption: (item) => {
254
+ const option = options.find((option) => option.level === item.value);
255
+ const Icon = (option === null || option === void 0 ? void 0 : option.icon) || IconH1;
256
+ return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [_jsx(Icon, { size: 14 }), item.label] }));
257
+ }, size: "xs", variant: "outlined", buttonProps: {
258
+ title: (currentHeading === null || currentHeading === void 0 ? void 0 : currentHeading.label) || "Heading",
259
+ "aria-label": "Heading",
260
+ disabled: !editor,
261
+ selected: Boolean(currentHeading),
262
+ style: { padding: "1px 6px" },
263
+ }, dropDownProps: {
264
+ style: {
265
+ width: 150,
266
+ },
267
+ }, children: _jsx(ButtonIcon, { size: 14 }) }));
268
+ };
207
269
  export const BulletListControl = ({ editor }) => {
208
270
  return (_jsx(Control, { editor: editor, label: "bulletListControlLabel", isActive: {
209
271
  name: "bulletList",
@@ -218,6 +280,51 @@ export const OrderedListControl = ({ editor }) => {
218
280
  name: "toggleOrderedList",
219
281
  }, icon: IconListNumbers }));
220
282
  };
283
+ export const TaskListControl = ({ editor }) => {
284
+ return (_jsx(Control, { editor: editor, label: "taskListControlLabel", isActive: {
285
+ name: "taskList",
286
+ }, operation: {
287
+ name: "toggleTaskList",
288
+ }, icon: ListChecksIcon }));
289
+ };
290
+ export const ListControl = ({ editor, listTypes = ["bullet", "ordered", "task"], }) => {
291
+ const options = listControlOptions.filter((option) => listTypes.includes(option.value));
292
+ const currentList = listControlOptions.find((option) => editor === null || editor === void 0 ? void 0 : editor.isActive(option.nodeName));
293
+ const selectedList = options.find((option) => option.value === (currentList === null || currentList === void 0 ? void 0 : currentList.value));
294
+ const fallbackList = options[0] || listControlOptions[0];
295
+ const ButtonIcon = (currentList === null || currentList === void 0 ? void 0 : currentList.icon) || fallbackList.icon;
296
+ if (!options.length)
297
+ return null;
298
+ return (_jsx(DropDownMenu, { data: options.map((option) => ({
299
+ label: option.label,
300
+ value: option.value,
301
+ onClick: () => {
302
+ const chain = editor === null || editor === void 0 ? void 0 : editor.chain().focus();
303
+ if (option.value === "bullet")
304
+ chain === null || chain === void 0 ? void 0 : chain.toggleBulletList().run();
305
+ if (option.value === "ordered")
306
+ chain === null || chain === void 0 ? void 0 : chain.toggleOrderedList().run();
307
+ if (option.value === "task")
308
+ chain === null || chain === void 0 ? void 0 : chain.toggleTaskList().run();
309
+ },
310
+ })), value: selectedList
311
+ ? [{ label: selectedList.label, value: selectedList.value }]
312
+ : [], enableSelectedOptionStyling: true, renderOption: (item) => {
313
+ const option = options.find((option) => option.value === item.value);
314
+ const Icon = (option === null || option === void 0 ? void 0 : option.icon) || IconList;
315
+ return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [_jsx(Icon, { size: 14 }), item.label] }));
316
+ }, size: "xs", variant: "outlined", buttonProps: {
317
+ title: (currentList === null || currentList === void 0 ? void 0 : currentList.label) || "List",
318
+ "aria-label": "List",
319
+ disabled: !editor,
320
+ selected: Boolean(currentList),
321
+ style: { padding: "1px 6px" },
322
+ }, dropDownProps: {
323
+ style: {
324
+ width: 150,
325
+ },
326
+ }, children: _jsx(ButtonIcon, { size: 14 }) }));
327
+ };
221
328
  export const AlignLeftControl = ({ editor }) => {
222
329
  return (_jsx(Control, { editor: editor, label: "alignLeftControlLabel", isActive: {
223
330
  name: { textAlign: "left" },
@@ -247,3 +354,35 @@ export const AlignJustifiedControl = ({ editor }) => {
247
354
  name: { textAlign: "justify" },
248
355
  }, operation: { name: "setTextAlign", attributes: "justify" }, icon: IconAlignJustified }));
249
356
  };
357
+ export const AlignmentControl = ({ editor, alignments = ["left", "center", "right", "justify"], }) => {
358
+ const options = alignmentControlOptions.filter((option) => alignments.includes(option.value));
359
+ const activeAlignment = alignmentControlOptions.find((option) => editor === null || editor === void 0 ? void 0 : editor.isActive({ textAlign: option.value }));
360
+ const currentAlignment = activeAlignment || alignmentControlOptions[0];
361
+ const selectedAlignment = options.find((option) => option.value === currentAlignment.value);
362
+ const ButtonIcon = currentAlignment.icon;
363
+ if (!options.length)
364
+ return null;
365
+ return (_jsx(DropDownMenu, { data: options.map((option) => ({
366
+ label: option.label,
367
+ value: option.value,
368
+ onClick: () => {
369
+ editor === null || editor === void 0 ? void 0 : editor.chain().focus().setTextAlign(option.value).run();
370
+ },
371
+ })), value: selectedAlignment
372
+ ? [{ label: selectedAlignment.label, value: selectedAlignment.value }]
373
+ : [], enableSelectedOptionStyling: true, renderOption: (item) => {
374
+ const option = options.find((option) => option.value === item.value);
375
+ const Icon = (option === null || option === void 0 ? void 0 : option.icon) || IconAlignLeft;
376
+ return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [_jsx(Icon, { size: 14 }), item.label] }));
377
+ }, size: "xs", variant: "outlined", buttonProps: {
378
+ title: currentAlignment.label,
379
+ "aria-label": "Text alignment",
380
+ disabled: !editor,
381
+ selected: Boolean(activeAlignment),
382
+ style: { padding: "1px 6px" },
383
+ }, dropDownProps: {
384
+ style: {
385
+ width: 170,
386
+ },
387
+ }, children: _jsx(ButtonIcon, { size: 14 }) }));
388
+ };
@@ -10,6 +10,7 @@ declare const Labels: {
10
10
  unlinkControlLabel: string;
11
11
  bulletListControlLabel: string;
12
12
  orderedListControlLabel: string;
13
+ taskListControlLabel: string;
13
14
  h1ControlLabel: string;
14
15
  h2ControlLabel: string;
15
16
  h3ControlLabel: string;
@@ -12,6 +12,7 @@ const Labels = {
12
12
  unlinkControlLabel: "Remove link",
13
13
  bulletListControlLabel: "Bullet list",
14
14
  orderedListControlLabel: "Ordered list",
15
+ taskListControlLabel: "Task list",
15
16
  h1ControlLabel: "Heading 1",
16
17
  h2ControlLabel: "Heading 2",
17
18
  h3ControlLabel: "Heading 3",
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import styled from "styled-components";
3
3
  import ControlsGroup from "./ControlsGroup";
4
- import { UndoControl, RedoControl, FontControl, TextColorControl, HighlightControl, BoldControl, ItalicControl, UnderlineControl, StrikeThroughControl, ClearFormattingControl, CodeControl, CodeBlockControl, BlockquoteControl, HorizontalRuleControl, Heading1Control, Heading2Control, Heading3Control, Heading4Control, BulletListControl, OrderedListControl, AlignLeftControl, AlignCenterControl, AlignRightControl, AlignJustifiedControl, } from "./Controls";
4
+ import { UndoControl, RedoControl, FontControl, TextColorControl, HighlightControl, BoldControl, ItalicControl, UnderlineControl, StrikeThroughControl, ClearFormattingControl, CodeControl, CodeBlockControl, BlockquoteControl, HorizontalRuleControl, HeadingControl, ListControl, AlignmentControl, } from "./Controls";
5
5
  import { Controls } from "../Enums";
6
6
  import { DropDownMenu } from "../../DropDownMenu";
7
7
  import { useState } from "react";
@@ -10,6 +10,23 @@ import { Popover } from "../../Popover";
10
10
  import LinkEditor from "../Components/LinkEditor";
11
11
  import { TableToolsPopover } from "../Components/TableTools";
12
12
  import { LinkIcon } from "lucide-react";
13
+ const headingControlLevels = [
14
+ { control: Controls.HEADING_1, level: 1 },
15
+ { control: Controls.HEADING_2, level: 2 },
16
+ { control: Controls.HEADING_3, level: 3 },
17
+ { control: Controls.HEADING_4, level: 4 },
18
+ ];
19
+ const alignmentControls = [
20
+ { control: Controls.TEXT_ALIGN_LEFT, alignment: "left" },
21
+ { control: Controls.TEXT_ALIGN_CENTER, alignment: "center" },
22
+ { control: Controls.TEXT_ALIGN_RIGHT, alignment: "right" },
23
+ { control: Controls.TEXT_ALIGN_JUSTIFIED, alignment: "justify" },
24
+ ];
25
+ const listControls = [
26
+ { control: Controls.BULLET_LIST, listType: "bullet" },
27
+ { control: Controls.ORDERED_LIST, listType: "ordered" },
28
+ { control: Controls.TASK_LIST, listType: "task" },
29
+ ];
13
30
  const ToolbarContainer = styled.div `
14
31
  display: flex;
15
32
  flex-direction: row;
@@ -32,6 +49,15 @@ export const Toolbar = ({ editor, toolbarOptions }) => {
32
49
  var _a;
33
50
  const { controls } = toolbarOptions || {};
34
51
  const [linkPopoverOpen, setLinkPopoverOpen] = useState(false);
52
+ const headingLevels = headingControlLevels
53
+ .filter(({ control }) => controls === null || controls === void 0 ? void 0 : controls.includes(control))
54
+ .map(({ level }) => level);
55
+ const alignments = alignmentControls
56
+ .filter(({ control }) => controls === null || controls === void 0 ? void 0 : controls.includes(control))
57
+ .map(({ alignment }) => alignment);
58
+ const listTypes = listControls
59
+ .filter(({ control }) => controls === null || controls === void 0 ? void 0 : controls.includes(control))
60
+ .map(({ listType }) => listType);
35
61
  const customItems = controls === null || controls === void 0 ? void 0 : controls.filter((control) => typeof control !== "string" &&
36
62
  (control.type === "menu" || control.type === "button"));
37
63
  return (_jsxs(ToolbarContainer, { children: [(_a = customItems === null || customItems === void 0 ? void 0 : customItems.map) === null || _a === void 0 ? void 0 : _a.call(customItems, (item, index) => {
@@ -46,5 +72,5 @@ export const Toolbar = ({ editor, toolbarOptions }) => {
46
72
  },
47
73
  } }, item.options, { size: "xs", children: (_b = item === null || item === void 0 ? void 0 : item.options) === null || _b === void 0 ? void 0 : _b.label }), index));
48
74
  }
49
- }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.UNDO)) && _jsx(UndoControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.REDO)) && _jsx(RedoControl, { editor: editor })] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.FONT)) && _jsx(FontControl, {}), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.COLOR)) && (_jsx(TextColorControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HIGHLIGHT)) && (_jsx(HighlightControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BOLD)) && _jsx(BoldControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.ITALIC)) && (_jsx(ItalicControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.UNDERLINE)) && (_jsx(UnderlineControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.STRIKE)) && (_jsx(StrikeThroughControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_1)) && (_jsx(Heading1Control, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_2)) && (_jsx(Heading2Control, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_3)) && (_jsx(Heading3Control, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_4)) && (_jsx(Heading4Control, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BULLET_LIST)) && (_jsx(BulletListControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.ORDERED_LIST)) && (_jsx(OrderedListControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BLOCKQUOTE)) && (_jsx(BlockquoteControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HORIZONTAL_RULE)) && (_jsx(HorizontalRuleControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_LEFT)) && (_jsx(AlignLeftControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_CENTER)) && (_jsx(AlignCenterControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_RIGHT)) && (_jsx(AlignRightControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_JUSTIFIED)) && (_jsx(AlignJustifiedControl, { editor: editor }))] }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.LINK)) && (_jsxs(Popover, { opened: linkPopoverOpen, onChange: setLinkPopoverOpen, position: "bottom", width: 330, trapFocus: true, children: [_jsx(Popover.Target, { children: _jsx(Button, { size: "xs", variant: "outlined", title: "Link", "aria-label": "Link", selected: linkPopoverOpen || Boolean(editor === null || editor === void 0 ? void 0 : editor.isActive("link")), disabled: !editor, style: { padding: "1px 6px" }, children: _jsx(LinkIcon, { size: 14 }) }) }), _jsx(Popover.Dropdown, { children: editor && (_jsx(LinkEditor, { editor: editor, autoFocus: linkPopoverOpen, onClose: () => setLinkPopoverOpen(false) })) })] })), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE)) && _jsx(CodeControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE_BLOCK)) && (_jsx(CodeBlockControl, { editor: editor }))] }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TABLE)) && (_jsx(TableToolsPopover, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CLEAR_FORMATTING)) && (_jsx(ClearFormattingControl, { editor: editor }))] }));
75
+ }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.UNDO)) && _jsx(UndoControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.REDO)) && _jsx(RedoControl, { editor: editor })] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.FONT)) && _jsx(FontControl, {}), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.COLOR)) && (_jsx(TextColorControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HIGHLIGHT)) && (_jsx(HighlightControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BOLD)) && _jsx(BoldControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.ITALIC)) && (_jsx(ItalicControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.UNDERLINE)) && (_jsx(UnderlineControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.STRIKE)) && (_jsx(StrikeThroughControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [headingLevels.length > 0 && (_jsx(HeadingControl, { editor: editor, levels: headingLevels })), alignments.length > 0 && (_jsx(AlignmentControl, { editor: editor, alignments: alignments })), listTypes.length > 0 && (_jsx(ListControl, { editor: editor, listTypes: listTypes })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BLOCKQUOTE)) && (_jsx(BlockquoteControl, { editor: editor }))] }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.LINK)) && (_jsxs(Popover, { opened: linkPopoverOpen, onChange: setLinkPopoverOpen, position: "bottom", width: 330, trapFocus: true, children: [_jsx(Popover.Target, { children: _jsx(Button, { size: "xs", variant: "outlined", title: "Link", "aria-label": "Link", selected: linkPopoverOpen || Boolean(editor === null || editor === void 0 ? void 0 : editor.isActive("link")), disabled: !editor, style: { padding: "1px 6px" }, children: _jsx(LinkIcon, { size: 14 }) }) }), _jsx(Popover.Dropdown, { children: editor && (_jsx(LinkEditor, { editor: editor, autoFocus: linkPopoverOpen, onClose: () => setLinkPopoverOpen(false) })) })] })), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE)) && _jsx(CodeControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE_BLOCK)) && (_jsx(CodeBlockControl, { editor: editor }))] }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TABLE)) && (_jsx(TableToolsPopover, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HORIZONTAL_RULE)) && (_jsx(HorizontalRuleControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CLEAR_FORMATTING)) && (_jsx(ClearFormattingControl, { editor: editor }))] }));
50
76
  };
@@ -0,0 +1,3 @@
1
+ import { ResizeHandlerProps } from "../types";
2
+ declare const resizeHandler: ({ event, columnId, columnProps, onResize, onResizeFinished, }: ResizeHandlerProps) => void;
3
+ export default resizeHandler;
@@ -0,0 +1,84 @@
1
+ import TableDefaults from "../TableDefaults";
2
+ const enableResizeClass = (dataField) => {
3
+ if (dataField === undefined) {
4
+ return;
5
+ }
6
+ document.querySelectorAll(`.resizer.col-${dataField}`).forEach((resizer) => {
7
+ resizer.classList.add("isResizing");
8
+ });
9
+ };
10
+ const disableResizeClass = (dataField) => {
11
+ if (dataField === undefined) {
12
+ return;
13
+ }
14
+ document.querySelectorAll(`.resizer.col-${dataField}`).forEach((resizer) => {
15
+ resizer.classList.remove("isResizing");
16
+ });
17
+ };
18
+ const resizeHandler = ({ event, columnId, columnProps, onResize, onResizeFinished, }) => {
19
+ let col = event.target
20
+ .parentElement;
21
+ let newColumns = [];
22
+ let x = 0;
23
+ let w = 0;
24
+ const mouseMoveHandler = function (e) {
25
+ const selectedColumn = document.querySelectorAll(`.column-${columnId}`);
26
+ const columnHeaders = document.querySelectorAll(`.mfui-th.column-${columnId}`);
27
+ const dx = e.clientX - x;
28
+ let newWidth = w + dx;
29
+ // Calculate what the minimum width should be
30
+ // min width should be the defined column width or the default min width
31
+ if (columnProps.minWidth === undefined) {
32
+ if (newWidth < TableDefaults.td.minWidth)
33
+ newWidth = TableDefaults.td.minWidth;
34
+ }
35
+ else {
36
+ if (newWidth < columnProps.minWidth)
37
+ newWidth = columnProps.minWidth;
38
+ }
39
+ selectedColumn.forEach((col) => {
40
+ var _a;
41
+ col.style.width = `${newWidth}px`;
42
+ col.style.flex = "0 0 auto";
43
+ // col.style.maxWidth = `${newWidth}px`;
44
+ // col.style.minWidth = `${newWidth}px`;
45
+ newColumns.push({
46
+ dataField: ((_a = col === null || col === void 0 ? void 0 : col.dataset) === null || _a === void 0 ? void 0 : _a.field) || "",
47
+ width: newWidth,
48
+ });
49
+ });
50
+ newColumns = Array.from(columnHeaders).map((col) => {
51
+ var _a;
52
+ return {
53
+ dataField: ((_a = col === null || col === void 0 ? void 0 : col.dataset) === null || _a === void 0 ? void 0 : _a.field) || "",
54
+ width: newWidth,
55
+ };
56
+ });
57
+ onResize({
58
+ columns: newColumns,
59
+ });
60
+ };
61
+ const mouseUpHandler = function () {
62
+ var _a, _b, _c;
63
+ let newWidth = ((_c = (_b = (_a = document === null || document === void 0 ? void 0 : document.querySelector) === null || _a === void 0 ? void 0 : _a.call(document, `.column-${columnId}`)) === null || _b === void 0 ? void 0 : _b.style) === null || _c === void 0 ? void 0 : _c.width) || null;
64
+ if (newWidth) {
65
+ newWidth = newWidth.replace("px", "");
66
+ }
67
+ disableResizeClass(columnId);
68
+ document.removeEventListener("mousemove", mouseMoveHandler);
69
+ document.removeEventListener("mouseup", mouseUpHandler);
70
+ onResizeFinished === null || onResizeFinished === void 0 ? void 0 : onResizeFinished({
71
+ column: columnProps,
72
+ columnId: columnId,
73
+ targetColumn: document.querySelector(`.column-${columnId}`),
74
+ newWidth,
75
+ });
76
+ };
77
+ x = event.clientX;
78
+ const styles = window.getComputedStyle(col);
79
+ w = parseInt(styles.width, 10);
80
+ document.addEventListener("mousemove", mouseMoveHandler);
81
+ document.addEventListener("mouseup", mouseUpHandler);
82
+ enableResizeClass(columnId);
83
+ };
84
+ export default resizeHandler;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monolith-forensics/monolith-ui",
3
- "version": "1.9.3-dev.4",
3
+ "version": "2.0.0",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Matt Danner (Monolith Forensics LLC)",
@@ -48,7 +48,10 @@
48
48
  "@tiptap/extension-horizontal-rule": "3.22.4",
49
49
  "@tiptap/extension-image": "3.22.4",
50
50
  "@tiptap/extension-link": "3.22.4",
51
+ "@tiptap/extension-list": "3.22.4",
51
52
  "@tiptap/extension-table": "3.22.4",
53
+ "@tiptap/extension-task-item": "3.22.4",
54
+ "@tiptap/extension-task-list": "3.22.4",
52
55
  "@tiptap/extension-text-align": "3.22.4",
53
56
  "@tiptap/extension-text-style": "3.22.4",
54
57
  "@tiptap/extensions": "3.22.4",