@pixpilot/shadcn-ui 0.35.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/IconToggle.cjs +82 -0
- package/dist/IconToggle.d.cts +49 -0
- package/dist/IconToggle.d.ts +49 -0
- package/dist/IconToggle.js +78 -0
- package/dist/index.cjs +5 -0
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/rich-text-editor/RichTextEditor.cjs +15 -2
- package/dist/rich-text-editor/RichTextEditor.js +13 -2
- package/dist/rich-text-editor/ToolbarButton.cjs +4 -11
- package/dist/rich-text-editor/ToolbarButton.js +1 -8
- package/dist/rich-text-editor/predefined-toolbar-items.cjs +24 -0
- package/dist/rich-text-editor/predefined-toolbar-items.js +25 -1
- package/dist/theme-toggle/ThemeModeDropdown.d.cts +2 -2
- package/dist/theme-toggle/ThemeModeSwitchInside.d.cts +2 -2
- package/dist/theme-toggle/ThemeModeSwitchOutside.d.cts +2 -2
- package/dist/theme-toggle/ThemeModeToggleButton.d.cts +2 -2
- package/dist/utils/svg.cjs +25 -0
- package/dist/utils/svg.d.cts +16 -0
- package/dist/utils/svg.d.ts +16 -0
- package/dist/utils/svg.js +23 -0
- package/package.json +8 -6
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_svg = require('./utils/svg.cjs');
|
|
3
|
+
let __pixpilot_shadcn = require("@pixpilot/shadcn");
|
|
4
|
+
__pixpilot_shadcn = require_rolldown_runtime.__toESM(__pixpilot_shadcn);
|
|
5
|
+
let react = require("react");
|
|
6
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
9
|
+
|
|
10
|
+
//#region src/IconToggle.tsx
|
|
11
|
+
/**
|
|
12
|
+
* IconToggle - A toggle button component with customizable icons for checked/unchecked states.
|
|
13
|
+
* Perfect for visibility toggles, theme switches, or any boolean state with visual feedback.
|
|
14
|
+
* Icons can be React components (like lucide-react icons) or SVG markup strings.
|
|
15
|
+
*/
|
|
16
|
+
const IconToggle = react.default.forwardRef(({ checked: controlledChecked, defaultChecked = false, onCheckedChange, onChange, checkedIcon, uncheckedIcon, size = "default", variant = "default", className, disabled,...props }, ref) => {
|
|
17
|
+
const [uncontrolledChecked, setUncontrolledChecked] = react.default.useState(defaultChecked);
|
|
18
|
+
const isControlled = controlledChecked !== void 0;
|
|
19
|
+
const checked = isControlled ? controlledChecked : uncontrolledChecked;
|
|
20
|
+
const handleClick = (0, react.useCallback)((e) => {
|
|
21
|
+
if (disabled) return;
|
|
22
|
+
const newChecked = !checked;
|
|
23
|
+
if (!isControlled) setUncontrolledChecked(newChecked);
|
|
24
|
+
onCheckedChange?.(newChecked);
|
|
25
|
+
onChange?.(newChecked);
|
|
26
|
+
props.onClick?.(e);
|
|
27
|
+
}, [
|
|
28
|
+
checked,
|
|
29
|
+
disabled,
|
|
30
|
+
isControlled,
|
|
31
|
+
onChange,
|
|
32
|
+
onCheckedChange,
|
|
33
|
+
props
|
|
34
|
+
]);
|
|
35
|
+
const renderIcon = (icon) => {
|
|
36
|
+
if (icon === void 0 || icon === null) return null;
|
|
37
|
+
if (require_svg.isSvgMarkupString(icon)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38
|
+
"data-slot": "svg-mask",
|
|
39
|
+
"aria-hidden": "true",
|
|
40
|
+
className: "inline-block h-4 w-4",
|
|
41
|
+
style: {
|
|
42
|
+
backgroundColor: "currentColor",
|
|
43
|
+
WebkitMaskImage: require_svg.svgMarkupToMaskUrl(icon),
|
|
44
|
+
maskImage: require_svg.svgMarkupToMaskUrl(icon),
|
|
45
|
+
WebkitMaskRepeat: "no-repeat",
|
|
46
|
+
maskRepeat: "no-repeat",
|
|
47
|
+
WebkitMaskPosition: "center",
|
|
48
|
+
maskPosition: "center",
|
|
49
|
+
WebkitMaskSize: "contain",
|
|
50
|
+
maskSize: "contain"
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return icon;
|
|
54
|
+
};
|
|
55
|
+
const sizeClasses = {
|
|
56
|
+
sm: "size-7",
|
|
57
|
+
default: "size-9",
|
|
58
|
+
lg: "size-11"
|
|
59
|
+
};
|
|
60
|
+
const variantClasses = {
|
|
61
|
+
default: "bg-background border border-input hover:bg-accent hover:text-accent-foreground data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:hover:bg-primary/90",
|
|
62
|
+
outline: "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground data-[state=checked]:border-primary data-[state=checked]:text-primary",
|
|
63
|
+
ghost: "hover:bg-accent hover:text-accent-foreground data-[state=checked]:bg-primary/10 data-[state=checked]:text-primary"
|
|
64
|
+
};
|
|
65
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
66
|
+
ref,
|
|
67
|
+
type: "button",
|
|
68
|
+
role: "switch",
|
|
69
|
+
"aria-checked": checked,
|
|
70
|
+
"data-state": checked ? "checked" : "unchecked",
|
|
71
|
+
"data-slot": "icon-toggle",
|
|
72
|
+
disabled,
|
|
73
|
+
className: (0, __pixpilot_shadcn.cn)("inline-flex items-center justify-center rounded-md text-sm font-medium transition-all outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50", "[&_svg]:pointer-events-none [&_svg:not([class*=\"size-\"])]:size-4 [&_svg]:shrink-0", sizeClasses[size], variantClasses[variant], className),
|
|
74
|
+
onClick: handleClick,
|
|
75
|
+
...props,
|
|
76
|
+
children: checked ? renderIcon(checkedIcon) : renderIcon(uncheckedIcon)
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
IconToggle.displayName = "IconToggle";
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
exports.IconToggle = IconToggle;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/IconToggle.d.ts
|
|
4
|
+
interface IconToggleProps extends Omit<React.ComponentProps<'button'>, 'onChange'> {
|
|
5
|
+
/**
|
|
6
|
+
* The checked/toggled state
|
|
7
|
+
*/
|
|
8
|
+
checked?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Default checked state for uncontrolled usage
|
|
11
|
+
*/
|
|
12
|
+
defaultChecked?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Called when the toggle state changes (controlled)
|
|
15
|
+
*/
|
|
16
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Called when the toggle state changes (alternative handler)
|
|
19
|
+
*/
|
|
20
|
+
onChange?: (checked: boolean) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Icon to show when checked (true state)
|
|
23
|
+
* Can be a React component (like lucide-react icons) or SVG markup string
|
|
24
|
+
*/
|
|
25
|
+
checkedIcon?: React.ReactNode | string;
|
|
26
|
+
/**
|
|
27
|
+
* Icon to show when unchecked (false state)
|
|
28
|
+
* Can be a React component (like lucide-react icons) or SVG markup string
|
|
29
|
+
*/
|
|
30
|
+
uncheckedIcon?: React.ReactNode | string;
|
|
31
|
+
/**
|
|
32
|
+
* Size variant of the toggle button
|
|
33
|
+
* @default 'default'
|
|
34
|
+
*/
|
|
35
|
+
size?: 'sm' | 'default' | 'lg';
|
|
36
|
+
/**
|
|
37
|
+
* Visual variant of the toggle button
|
|
38
|
+
* @default 'default'
|
|
39
|
+
*/
|
|
40
|
+
variant?: 'default' | 'outline' | 'ghost';
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* IconToggle - A toggle button component with customizable icons for checked/unchecked states.
|
|
44
|
+
* Perfect for visibility toggles, theme switches, or any boolean state with visual feedback.
|
|
45
|
+
* Icons can be React components (like lucide-react icons) or SVG markup strings.
|
|
46
|
+
*/
|
|
47
|
+
declare const IconToggle: React.ForwardRefExoticComponent<Omit<IconToggleProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { IconToggle, IconToggleProps };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/IconToggle.d.ts
|
|
4
|
+
interface IconToggleProps extends Omit<React.ComponentProps<'button'>, 'onChange'> {
|
|
5
|
+
/**
|
|
6
|
+
* The checked/toggled state
|
|
7
|
+
*/
|
|
8
|
+
checked?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Default checked state for uncontrolled usage
|
|
11
|
+
*/
|
|
12
|
+
defaultChecked?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Called when the toggle state changes (controlled)
|
|
15
|
+
*/
|
|
16
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Called when the toggle state changes (alternative handler)
|
|
19
|
+
*/
|
|
20
|
+
onChange?: (checked: boolean) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Icon to show when checked (true state)
|
|
23
|
+
* Can be a React component (like lucide-react icons) or SVG markup string
|
|
24
|
+
*/
|
|
25
|
+
checkedIcon?: React.ReactNode | string;
|
|
26
|
+
/**
|
|
27
|
+
* Icon to show when unchecked (false state)
|
|
28
|
+
* Can be a React component (like lucide-react icons) or SVG markup string
|
|
29
|
+
*/
|
|
30
|
+
uncheckedIcon?: React.ReactNode | string;
|
|
31
|
+
/**
|
|
32
|
+
* Size variant of the toggle button
|
|
33
|
+
* @default 'default'
|
|
34
|
+
*/
|
|
35
|
+
size?: 'sm' | 'default' | 'lg';
|
|
36
|
+
/**
|
|
37
|
+
* Visual variant of the toggle button
|
|
38
|
+
* @default 'default'
|
|
39
|
+
*/
|
|
40
|
+
variant?: 'default' | 'outline' | 'ghost';
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* IconToggle - A toggle button component with customizable icons for checked/unchecked states.
|
|
44
|
+
* Perfect for visibility toggles, theme switches, or any boolean state with visual feedback.
|
|
45
|
+
* Icons can be React components (like lucide-react icons) or SVG markup strings.
|
|
46
|
+
*/
|
|
47
|
+
declare const IconToggle: React.ForwardRefExoticComponent<Omit<IconToggleProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { IconToggle, IconToggleProps };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { isSvgMarkupString, svgMarkupToMaskUrl } from "./utils/svg.js";
|
|
2
|
+
import { cn } from "@pixpilot/shadcn";
|
|
3
|
+
import React, { useCallback } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/IconToggle.tsx
|
|
7
|
+
/**
|
|
8
|
+
* IconToggle - A toggle button component with customizable icons for checked/unchecked states.
|
|
9
|
+
* Perfect for visibility toggles, theme switches, or any boolean state with visual feedback.
|
|
10
|
+
* Icons can be React components (like lucide-react icons) or SVG markup strings.
|
|
11
|
+
*/
|
|
12
|
+
const IconToggle = React.forwardRef(({ checked: controlledChecked, defaultChecked = false, onCheckedChange, onChange, checkedIcon, uncheckedIcon, size = "default", variant = "default", className, disabled,...props }, ref) => {
|
|
13
|
+
const [uncontrolledChecked, setUncontrolledChecked] = React.useState(defaultChecked);
|
|
14
|
+
const isControlled = controlledChecked !== void 0;
|
|
15
|
+
const checked = isControlled ? controlledChecked : uncontrolledChecked;
|
|
16
|
+
const handleClick = useCallback((e) => {
|
|
17
|
+
if (disabled) return;
|
|
18
|
+
const newChecked = !checked;
|
|
19
|
+
if (!isControlled) setUncontrolledChecked(newChecked);
|
|
20
|
+
onCheckedChange?.(newChecked);
|
|
21
|
+
onChange?.(newChecked);
|
|
22
|
+
props.onClick?.(e);
|
|
23
|
+
}, [
|
|
24
|
+
checked,
|
|
25
|
+
disabled,
|
|
26
|
+
isControlled,
|
|
27
|
+
onChange,
|
|
28
|
+
onCheckedChange,
|
|
29
|
+
props
|
|
30
|
+
]);
|
|
31
|
+
const renderIcon = (icon) => {
|
|
32
|
+
if (icon === void 0 || icon === null) return null;
|
|
33
|
+
if (isSvgMarkupString(icon)) return /* @__PURE__ */ jsx("span", {
|
|
34
|
+
"data-slot": "svg-mask",
|
|
35
|
+
"aria-hidden": "true",
|
|
36
|
+
className: "inline-block h-4 w-4",
|
|
37
|
+
style: {
|
|
38
|
+
backgroundColor: "currentColor",
|
|
39
|
+
WebkitMaskImage: svgMarkupToMaskUrl(icon),
|
|
40
|
+
maskImage: svgMarkupToMaskUrl(icon),
|
|
41
|
+
WebkitMaskRepeat: "no-repeat",
|
|
42
|
+
maskRepeat: "no-repeat",
|
|
43
|
+
WebkitMaskPosition: "center",
|
|
44
|
+
maskPosition: "center",
|
|
45
|
+
WebkitMaskSize: "contain",
|
|
46
|
+
maskSize: "contain"
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
return icon;
|
|
50
|
+
};
|
|
51
|
+
const sizeClasses = {
|
|
52
|
+
sm: "size-7",
|
|
53
|
+
default: "size-9",
|
|
54
|
+
lg: "size-11"
|
|
55
|
+
};
|
|
56
|
+
const variantClasses = {
|
|
57
|
+
default: "bg-background border border-input hover:bg-accent hover:text-accent-foreground data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:hover:bg-primary/90",
|
|
58
|
+
outline: "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground data-[state=checked]:border-primary data-[state=checked]:text-primary",
|
|
59
|
+
ghost: "hover:bg-accent hover:text-accent-foreground data-[state=checked]:bg-primary/10 data-[state=checked]:text-primary"
|
|
60
|
+
};
|
|
61
|
+
return /* @__PURE__ */ jsx("button", {
|
|
62
|
+
ref,
|
|
63
|
+
type: "button",
|
|
64
|
+
role: "switch",
|
|
65
|
+
"aria-checked": checked,
|
|
66
|
+
"data-state": checked ? "checked" : "unchecked",
|
|
67
|
+
"data-slot": "icon-toggle",
|
|
68
|
+
disabled,
|
|
69
|
+
className: cn("inline-flex items-center justify-center rounded-md text-sm font-medium transition-all outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50", "[&_svg]:pointer-events-none [&_svg:not([class*=\"size-\"])]:size-4 [&_svg]:shrink-0", sizeClasses[size], variantClasses[variant], className),
|
|
70
|
+
onClick: handleClick,
|
|
71
|
+
...props,
|
|
72
|
+
children: checked ? renderIcon(checkedIcon) : renderIcon(uncheckedIcon)
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
IconToggle.displayName = "IconToggle";
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { IconToggle };
|
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,8 @@ require('./input/index.cjs');
|
|
|
31
31
|
const require_LoadingOverlay = require('./LoadingOverlay.cjs');
|
|
32
32
|
const require_IconPicker = require('./icon-selector/IconPicker.cjs');
|
|
33
33
|
require('./icon-selector/index.cjs');
|
|
34
|
+
const require_svg = require('./utils/svg.cjs');
|
|
35
|
+
const require_IconToggle = require('./IconToggle.cjs');
|
|
34
36
|
const require_Layout = require('./layout/Layout.cjs');
|
|
35
37
|
const require_LayoutFooter = require('./layout/LayoutFooter.cjs');
|
|
36
38
|
const require_LayoutHeader = require('./layout/LayoutHeader.cjs');
|
|
@@ -84,6 +86,7 @@ exports.DialogProvider = require_DialogProvider.DialogProvider;
|
|
|
84
86
|
exports.FileUpload = require_FileUpload.FileUpload;
|
|
85
87
|
exports.FileUploadInline = require_FileUploadInline.FileUploadInline;
|
|
86
88
|
exports.IconPicker = require_IconPicker.IconPicker;
|
|
89
|
+
exports.IconToggle = require_IconToggle.IconToggle;
|
|
87
90
|
exports.Input = require_Input.Input;
|
|
88
91
|
exports.Layout = require_Layout.Layout;
|
|
89
92
|
exports.LayoutFooter = require_LayoutFooter.LayoutFooter;
|
|
@@ -110,7 +113,9 @@ exports.ThemeModeToggleButton = require_ThemeModeToggleButton.ThemeModeToggleBut
|
|
|
110
113
|
exports.ThemeProvider = require_ThemeProvider.ThemeProvider;
|
|
111
114
|
exports.Toaster = require_ToastProvider.Toaster;
|
|
112
115
|
exports.cn = __pixpilot_shadcn.cn;
|
|
116
|
+
exports.isSvgMarkupString = require_svg.isSvgMarkupString;
|
|
113
117
|
exports.showConfirmDialog = require_confirmation_dialogs.showConfirmDialog;
|
|
118
|
+
exports.svgMarkupToMaskUrl = require_svg.svgMarkupToMaskUrl;
|
|
114
119
|
exports.toast = require_toast.toast;
|
|
115
120
|
exports.toastError = require_toast.toastError;
|
|
116
121
|
exports.toastInfo = require_toast.toastInfo;
|
package/dist/index.d.cts
CHANGED
|
@@ -30,6 +30,7 @@ import "./hooks/index.cjs";
|
|
|
30
30
|
import { IconProvider, IconProviderLoader, IconProviderProps } from "./icon-selector/types.cjs";
|
|
31
31
|
import { IconPicker, IconPickerProps, IconPickerVariant } from "./icon-selector/IconPicker.cjs";
|
|
32
32
|
import "./icon-selector/index.cjs";
|
|
33
|
+
import { IconToggle, IconToggleProps } from "./IconToggle.cjs";
|
|
33
34
|
import { Input, InputProps } from "./input/Input.cjs";
|
|
34
35
|
import "./input/index.cjs";
|
|
35
36
|
import { Layout, LayoutProps } from "./layout/Layout.cjs";
|
|
@@ -66,5 +67,6 @@ import "./theme-toggle/index.cjs";
|
|
|
66
67
|
import { DEFAULT_ALERT_DURATION, ToastMessage, toast, toastError, toastInfo, toastSuccess, toastWarning } from "./toast/toast.cjs";
|
|
67
68
|
import { Toaster } from "./toast/ToastProvider.cjs";
|
|
68
69
|
import "./toast/index.cjs";
|
|
70
|
+
import { isSvgMarkupString, svgMarkupToMaskUrl } from "./utils/svg.cjs";
|
|
69
71
|
import { cn } from "@pixpilot/shadcn";
|
|
70
|
-
export { AbsoluteFill, Alert, AlertBaseProps, AlertProps, AlertVariant, AvatarUpload, AvatarUploadProps, BaseTabsTriggerProps, Button, ButtonLoaderProps, ButtonProps, CircleLoader, CircleLoaderProps, CloseButtonAbsolute, CloseButtonRounded, CloseButtonRoundedProps, ColorPicker, ColorPickerBase, ColorPickerBaseProps, ColorPickerBaseSection, ColorPickerProps, ColorSelect, ColorSelectOption, BaseColorSelectProps as ColorSelectProps, Combobox, ConfirmationDialogProps, ContentCard, DEFAULT_ALERT_DURATION, DatePicker, DatePickerProps, DialogProvider, DialogProviderProps, type FileMetadata, FileUpload, FileUploadBaseProps, FileUploadInline, FileUploadInlineBaseProps, FileUploadInlineProps, type FileUploadProgressCallBacks, type FileUploadProps, IconPicker, IconPickerProps, IconPickerVariant, IconProvider, IconProviderLoader, IconProviderProps, Input, InputProps, Layout, LayoutFooter, LayoutFooterProps, LayoutHeader, LayoutHeaderProps, LayoutMain, LayoutMainProps, LayoutProps, LoaderProps, LoadingOverlay, MultiFileUploadProps, OnChangeMultipleFiles, OnChangeSingleFile, Pagination, PaginationProps, PopoverCloseButtonProps, PresetColor, RichTextEditor, RichTextEditorProps, RichTextEditorSlots, ScaledPreview, ScaledPreviewProps, ScaledPreviewSize, Select, SelectOption, SingleFileUploadProps, Slider, SliderInput, SliderInputProps, SliderProps, SliderSelect, SliderSelectOption, SliderSelectProps, SliderSelectValue, Tabs, TabsContent, TabsContext, TabsContextValue, TabsList, TabsListProps, TabsTrigger, TabsTriggerProps, TabsVariant, TagsInput, TagsInputProps, ThemeModeDropdown, ThemeModeDropdownProps, ThemeModeSwitchInside, ThemeModeSwitchInsideProps, ThemeModeSwitchInsideSize, ThemeModeSwitchOutside, ThemeModeSwitchOutsideProps, ThemeModeToggleButton, ThemeModeToggleButtonProps, ThemeProvider, ThemeProviderProps, ToastMessage, Toaster, ToolbarItems, cn, showConfirmDialog, toast, toastError, toastInfo, toastSuccess, toastWarning, useMediaQuery, useSelectKeyboard, useTabsContext, useTheme };
|
|
72
|
+
export { AbsoluteFill, Alert, AlertBaseProps, AlertProps, AlertVariant, AvatarUpload, AvatarUploadProps, BaseTabsTriggerProps, Button, ButtonLoaderProps, ButtonProps, CircleLoader, CircleLoaderProps, CloseButtonAbsolute, CloseButtonRounded, CloseButtonRoundedProps, ColorPicker, ColorPickerBase, ColorPickerBaseProps, ColorPickerBaseSection, ColorPickerProps, ColorSelect, ColorSelectOption, BaseColorSelectProps as ColorSelectProps, Combobox, ConfirmationDialogProps, ContentCard, DEFAULT_ALERT_DURATION, DatePicker, DatePickerProps, DialogProvider, DialogProviderProps, type FileMetadata, FileUpload, FileUploadBaseProps, FileUploadInline, FileUploadInlineBaseProps, FileUploadInlineProps, type FileUploadProgressCallBacks, type FileUploadProps, IconPicker, IconPickerProps, IconPickerVariant, IconProvider, IconProviderLoader, IconProviderProps, IconToggle, IconToggleProps, Input, InputProps, Layout, LayoutFooter, LayoutFooterProps, LayoutHeader, LayoutHeaderProps, LayoutMain, LayoutMainProps, LayoutProps, LoaderProps, LoadingOverlay, MultiFileUploadProps, OnChangeMultipleFiles, OnChangeSingleFile, Pagination, PaginationProps, PopoverCloseButtonProps, PresetColor, RichTextEditor, RichTextEditorProps, RichTextEditorSlots, ScaledPreview, ScaledPreviewProps, ScaledPreviewSize, Select, SelectOption, SingleFileUploadProps, Slider, SliderInput, SliderInputProps, SliderProps, SliderSelect, SliderSelectOption, SliderSelectProps, SliderSelectValue, Tabs, TabsContent, TabsContext, TabsContextValue, TabsList, TabsListProps, TabsTrigger, TabsTriggerProps, TabsVariant, TagsInput, TagsInputProps, ThemeModeDropdown, ThemeModeDropdownProps, ThemeModeSwitchInside, ThemeModeSwitchInsideProps, ThemeModeSwitchInsideSize, ThemeModeSwitchOutside, ThemeModeSwitchOutsideProps, ThemeModeToggleButton, ThemeModeToggleButtonProps, ThemeProvider, ThemeProviderProps, ToastMessage, Toaster, ToolbarItems, cn, isSvgMarkupString, showConfirmDialog, svgMarkupToMaskUrl, toast, toastError, toastInfo, toastSuccess, toastWarning, useMediaQuery, useSelectKeyboard, useTabsContext, useTheme };
|
package/dist/index.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ import "./hooks/index.js";
|
|
|
32
32
|
import { IconProvider, IconProviderLoader, IconProviderProps } from "./icon-selector/types.js";
|
|
33
33
|
import { IconPicker, IconPickerProps, IconPickerVariant } from "./icon-selector/IconPicker.js";
|
|
34
34
|
import "./icon-selector/index.js";
|
|
35
|
+
import { IconToggle, IconToggleProps } from "./IconToggle.js";
|
|
35
36
|
import { Input, InputProps } from "./input/Input.js";
|
|
36
37
|
import "./input/index.js";
|
|
37
38
|
import { Layout, LayoutProps } from "./layout/Layout.js";
|
|
@@ -68,5 +69,6 @@ import "./theme-toggle/index.js";
|
|
|
68
69
|
import { DEFAULT_ALERT_DURATION, ToastMessage, toast, toastError, toastInfo, toastSuccess, toastWarning } from "./toast/toast.js";
|
|
69
70
|
import { Toaster } from "./toast/ToastProvider.js";
|
|
70
71
|
import "./toast/index.js";
|
|
72
|
+
import { isSvgMarkupString, svgMarkupToMaskUrl } from "./utils/svg.js";
|
|
71
73
|
import { cn } from "@pixpilot/shadcn";
|
|
72
|
-
export { AbsoluteFill, Alert, AlertBaseProps, AlertProps, AlertVariant, AvatarUpload, AvatarUploadProps, BaseTabsTriggerProps, Button, ButtonLoaderProps, ButtonProps, CircleLoader, CircleLoaderProps, CloseButtonAbsolute, CloseButtonRounded, CloseButtonRoundedProps, ColorPicker, ColorPickerBase, ColorPickerBaseProps, ColorPickerBaseSection, ColorPickerProps, ColorSelect, ColorSelectOption, BaseColorSelectProps as ColorSelectProps, Combobox, ConfirmationDialogProps, ContentCard, DEFAULT_ALERT_DURATION, DatePicker, DatePickerProps, DialogProvider, DialogProviderProps, type FileMetadata, FileUpload, FileUploadBaseProps, FileUploadInline, FileUploadInlineBaseProps, FileUploadInlineProps, type FileUploadProgressCallBacks, type FileUploadProps, IconPicker, IconPickerProps, IconPickerVariant, IconProvider, IconProviderLoader, IconProviderProps, Input, InputProps, Layout, LayoutFooter, LayoutFooterProps, LayoutHeader, LayoutHeaderProps, LayoutMain, LayoutMainProps, LayoutProps, LoaderProps, LoadingOverlay, MultiFileUploadProps, OnChangeMultipleFiles, OnChangeSingleFile, Pagination, PaginationProps, PopoverCloseButtonProps, PresetColor, RichTextEditor, RichTextEditorProps, RichTextEditorSlots, ScaledPreview, ScaledPreviewProps, ScaledPreviewSize, Select, SelectOption, SingleFileUploadProps, Slider, SliderInput, SliderInputProps, SliderProps, SliderSelect, SliderSelectOption, SliderSelectProps, SliderSelectValue, Tabs, TabsContent, TabsContext, TabsContextValue, TabsList, TabsListProps, TabsTrigger, TabsTriggerProps, TabsVariant, TagsInput, TagsInputProps, ThemeModeDropdown, ThemeModeDropdownProps, ThemeModeSwitchInside, ThemeModeSwitchInsideProps, ThemeModeSwitchInsideSize, ThemeModeSwitchOutside, ThemeModeSwitchOutsideProps, ThemeModeToggleButton, ThemeModeToggleButtonProps, ThemeProvider, ThemeProviderProps, ToastMessage, Toaster, ToolbarItems, cn, showConfirmDialog, toast, toastError, toastInfo, toastSuccess, toastWarning, useMediaQuery, useSelectKeyboard, useTabsContext, useTheme };
|
|
74
|
+
export { AbsoluteFill, Alert, AlertBaseProps, AlertProps, AlertVariant, AvatarUpload, AvatarUploadProps, BaseTabsTriggerProps, Button, ButtonLoaderProps, ButtonProps, CircleLoader, CircleLoaderProps, CloseButtonAbsolute, CloseButtonRounded, CloseButtonRoundedProps, ColorPicker, ColorPickerBase, ColorPickerBaseProps, ColorPickerBaseSection, ColorPickerProps, ColorSelect, ColorSelectOption, BaseColorSelectProps as ColorSelectProps, Combobox, ConfirmationDialogProps, ContentCard, DEFAULT_ALERT_DURATION, DatePicker, DatePickerProps, DialogProvider, DialogProviderProps, type FileMetadata, FileUpload, FileUploadBaseProps, FileUploadInline, FileUploadInlineBaseProps, FileUploadInlineProps, type FileUploadProgressCallBacks, type FileUploadProps, IconPicker, IconPickerProps, IconPickerVariant, IconProvider, IconProviderLoader, IconProviderProps, IconToggle, IconToggleProps, Input, InputProps, Layout, LayoutFooter, LayoutFooterProps, LayoutHeader, LayoutHeaderProps, LayoutMain, LayoutMainProps, LayoutProps, LoaderProps, LoadingOverlay, MultiFileUploadProps, OnChangeMultipleFiles, OnChangeSingleFile, Pagination, PaginationProps, PopoverCloseButtonProps, PresetColor, RichTextEditor, RichTextEditorProps, RichTextEditorSlots, ScaledPreview, ScaledPreviewProps, ScaledPreviewSize, Select, SelectOption, SingleFileUploadProps, Slider, SliderInput, SliderInputProps, SliderProps, SliderSelect, SliderSelectOption, SliderSelectProps, SliderSelectValue, Tabs, TabsContent, TabsContext, TabsContextValue, TabsList, TabsListProps, TabsTrigger, TabsTriggerProps, TabsVariant, TagsInput, TagsInputProps, ThemeModeDropdown, ThemeModeDropdownProps, ThemeModeSwitchInside, ThemeModeSwitchInsideProps, ThemeModeSwitchInsideSize, ThemeModeSwitchOutside, ThemeModeSwitchOutsideProps, ThemeModeToggleButton, ThemeModeToggleButtonProps, ThemeProvider, ThemeProviderProps, ToastMessage, Toaster, ToolbarItems, cn, isSvgMarkupString, showConfirmDialog, svgMarkupToMaskUrl, toast, toastError, toastInfo, toastSuccess, toastWarning, useMediaQuery, useSelectKeyboard, useTabsContext, useTheme };
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,8 @@ import "./input/index.js";
|
|
|
30
30
|
import { LoadingOverlay } from "./LoadingOverlay.js";
|
|
31
31
|
import { IconPicker } from "./icon-selector/IconPicker.js";
|
|
32
32
|
import "./icon-selector/index.js";
|
|
33
|
+
import { isSvgMarkupString, svgMarkupToMaskUrl } from "./utils/svg.js";
|
|
34
|
+
import { IconToggle } from "./IconToggle.js";
|
|
33
35
|
import { Layout } from "./layout/Layout.js";
|
|
34
36
|
import { LayoutFooter } from "./layout/LayoutFooter.js";
|
|
35
37
|
import { LayoutHeader } from "./layout/LayoutHeader.js";
|
|
@@ -64,4 +66,4 @@ import { Toaster } from "./toast/ToastProvider.js";
|
|
|
64
66
|
import "./toast/index.js";
|
|
65
67
|
import { cn } from "@pixpilot/shadcn";
|
|
66
68
|
|
|
67
|
-
export { AbsoluteFill, Alert, AvatarUpload, Button, CircleLoader, CloseButtonAbsolute, CloseButtonRounded, ColorPicker, ColorPickerBase, ColorSelect, Combobox, ContentCard, DEFAULT_ALERT_DURATION, DatePicker, DialogProvider, FileUpload, FileUploadInline, IconPicker, Input, Layout, LayoutFooter, LayoutHeader, LayoutMain, LoadingOverlay, Pagination, RichTextEditor, ScaledPreview, Select, Slider, SliderInput, SliderSelect, Tabs, TabsContent, TabsContext, TabsList, TabsTrigger, TagsInput, ThemeModeDropdown, ThemeModeSwitchInside, ThemeModeSwitchOutside, ThemeModeToggleButton, ThemeProvider, Toaster, cn, showConfirmDialog, toast, toastError, toastInfo, toastSuccess, toastWarning, useMediaQuery, useSelectKeyboard, useTabsContext, useTheme };
|
|
69
|
+
export { AbsoluteFill, Alert, AvatarUpload, Button, CircleLoader, CloseButtonAbsolute, CloseButtonRounded, ColorPicker, ColorPickerBase, ColorSelect, Combobox, ContentCard, DEFAULT_ALERT_DURATION, DatePicker, DialogProvider, FileUpload, FileUploadInline, IconPicker, IconToggle, Input, Layout, LayoutFooter, LayoutHeader, LayoutMain, LoadingOverlay, Pagination, RichTextEditor, ScaledPreview, Select, Slider, SliderInput, SliderSelect, Tabs, TabsContent, TabsContext, TabsList, TabsTrigger, TagsInput, ThemeModeDropdown, ThemeModeSwitchInside, ThemeModeSwitchOutside, ThemeModeToggleButton, ThemeProvider, Toaster, cn, isSvgMarkupString, showConfirmDialog, svgMarkupToMaskUrl, toast, toastError, toastInfo, toastSuccess, toastWarning, useMediaQuery, useSelectKeyboard, useTabsContext, useTheme };
|
|
@@ -6,6 +6,10 @@ let react = require("react");
|
|
|
6
6
|
react = require_rolldown_runtime.__toESM(react);
|
|
7
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
8
|
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
9
|
+
let __tiptap_extension_link = require("@tiptap/extension-link");
|
|
10
|
+
__tiptap_extension_link = require_rolldown_runtime.__toESM(__tiptap_extension_link);
|
|
11
|
+
let __tiptap_extension_text_align = require("@tiptap/extension-text-align");
|
|
12
|
+
__tiptap_extension_text_align = require_rolldown_runtime.__toESM(__tiptap_extension_text_align);
|
|
9
13
|
let __tiptap_react = require("@tiptap/react");
|
|
10
14
|
__tiptap_react = require_rolldown_runtime.__toESM(__tiptap_react);
|
|
11
15
|
let __tiptap_starter_kit = require("@tiptap/starter-kit");
|
|
@@ -17,9 +21,14 @@ const defaultToolbarItems = [
|
|
|
17
21
|
"bold",
|
|
18
22
|
"italic",
|
|
19
23
|
"underline",
|
|
24
|
+
"link",
|
|
20
25
|
"strike",
|
|
21
26
|
"code",
|
|
22
27
|
"|",
|
|
28
|
+
"alignLeft",
|
|
29
|
+
"alignCenter",
|
|
30
|
+
"alignRight",
|
|
31
|
+
"|",
|
|
23
32
|
"heading1",
|
|
24
33
|
"heading2",
|
|
25
34
|
"heading3",
|
|
@@ -31,7 +40,7 @@ const defaultToolbarItems = [
|
|
|
31
40
|
"codeBlock"
|
|
32
41
|
];
|
|
33
42
|
function useEditorProps(slots, customEditorProps) {
|
|
34
|
-
const defaultEditorProps = react.default.useMemo(() => ({ attributes: { class: (0, __pixpilot_shadcn.cn)("min-h-[200px] p-4 text-sm leading-relaxed focus:outline-none", "[&_h1]:text-3xl [&_h1]:font-bold [&_h1]:leading-tight [&_h1]:mt-8 [&_h1]:mb-4 [&_h1:first-child]:mt-0", "[&_h2]:text-2xl [&_h2]:font-bold [&_h2]:leading-tight [&_h2]:mt-6 [&_h2]:mb-3 [&_h2:first-child]:mt-0", "[&_h3]:text-xl [&_h3]:font-bold [&_h3]:leading-tight [&_h3]:mt-4 [&_h3]:mb-2 [&_h3:first-child]:mt-0", "[&_p]:mb-3", "[&_ul]:list-disc [&_ul]:pl-6 [&_ul]:mb-3", "[&_ol]:list-decimal [&_ol]:pl-6 [&_ol]:mb-3", "[&_blockquote]:border-l-4 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:mb-4 [&_blockquote]:italic [&_blockquote:first-child]:mt-0", "[&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[0.875em] [&_code]:font-mono", "[&_pre]:bg-muted [&_pre]:p-4 [&_pre]:rounded [&_pre]:overflow-x-auto [&_pre]:font-mono [&_pre]:mb-4", "[&_*:last-child]:mb-0", slots?.content?.className) } }), [slots]);
|
|
43
|
+
const defaultEditorProps = react.default.useMemo(() => ({ attributes: { class: (0, __pixpilot_shadcn.cn)("min-h-[200px] p-4 text-sm leading-relaxed focus:outline-none", "[&_h1]:text-3xl [&_h1]:font-bold [&_h1]:leading-tight [&_h1]:mt-8 [&_h1]:mb-4 [&_h1:first-child]:mt-0", "[&_h2]:text-2xl [&_h2]:font-bold [&_h2]:leading-tight [&_h2]:mt-6 [&_h2]:mb-3 [&_h2:first-child]:mt-0", "[&_h3]:text-xl [&_h3]:font-bold [&_h3]:leading-tight [&_h3]:mt-4 [&_h3]:mb-2 [&_h3:first-child]:mt-0", "[&_p]:mb-3", "[&_ul]:list-disc [&_ul]:pl-6 [&_ul]:mb-3", "[&_ol]:list-decimal [&_ol]:pl-6 [&_ol]:mb-3", "[&_blockquote]:border-l-4 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:mb-4 [&_blockquote]:italic [&_blockquote:first-child]:mt-0", "[&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[0.875em] [&_code]:font-mono", "[&_pre]:bg-muted [&_pre]:p-4 [&_pre]:rounded [&_pre]:overflow-x-auto [&_pre]:font-mono [&_pre]:mb-4", "[&_a]:text-blue-500 [&_a]:hover:text-blue-600 [&_a]:cursor-pointer [&_a]:underline [&_a]:underline-offset-2 ", "[&_*:last-child]:mb-0", slots?.content?.className) } }), [slots]);
|
|
35
44
|
return react.default.useMemo(() => ({
|
|
36
45
|
...defaultEditorProps,
|
|
37
46
|
...customEditorProps,
|
|
@@ -51,7 +60,11 @@ const RichTextEditor = ({ value, onChange, extensions = defaultExtensions, edita
|
|
|
51
60
|
onChangeRef.current?.(props.editor.getHTML());
|
|
52
61
|
}, []);
|
|
53
62
|
const editorInstance = (0, __tiptap_react.useEditor)({
|
|
54
|
-
extensions:
|
|
63
|
+
extensions: react.default.useMemo(() => [
|
|
64
|
+
__tiptap_starter_kit.default,
|
|
65
|
+
__tiptap_extension_link.default,
|
|
66
|
+
__tiptap_extension_text_align.default.configure({ types: ["heading", "paragraph"] })
|
|
67
|
+
].concat(extensions), [extensions]),
|
|
55
68
|
content: value,
|
|
56
69
|
editable,
|
|
57
70
|
onUpdate: handleChange,
|
|
@@ -2,6 +2,8 @@ import { RichTextEditorToolbar } from "./RichTextEditorToolbar.js";
|
|
|
2
2
|
import { cn } from "@pixpilot/shadcn";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import Link from "@tiptap/extension-link";
|
|
6
|
+
import TextAlign from "@tiptap/extension-text-align";
|
|
5
7
|
import { EditorContent, useEditor } from "@tiptap/react";
|
|
6
8
|
import StarterKit from "@tiptap/starter-kit";
|
|
7
9
|
|
|
@@ -11,9 +13,14 @@ const defaultToolbarItems = [
|
|
|
11
13
|
"bold",
|
|
12
14
|
"italic",
|
|
13
15
|
"underline",
|
|
16
|
+
"link",
|
|
14
17
|
"strike",
|
|
15
18
|
"code",
|
|
16
19
|
"|",
|
|
20
|
+
"alignLeft",
|
|
21
|
+
"alignCenter",
|
|
22
|
+
"alignRight",
|
|
23
|
+
"|",
|
|
17
24
|
"heading1",
|
|
18
25
|
"heading2",
|
|
19
26
|
"heading3",
|
|
@@ -25,7 +32,7 @@ const defaultToolbarItems = [
|
|
|
25
32
|
"codeBlock"
|
|
26
33
|
];
|
|
27
34
|
function useEditorProps(slots, customEditorProps) {
|
|
28
|
-
const defaultEditorProps = React.useMemo(() => ({ attributes: { class: cn("min-h-[200px] p-4 text-sm leading-relaxed focus:outline-none", "[&_h1]:text-3xl [&_h1]:font-bold [&_h1]:leading-tight [&_h1]:mt-8 [&_h1]:mb-4 [&_h1:first-child]:mt-0", "[&_h2]:text-2xl [&_h2]:font-bold [&_h2]:leading-tight [&_h2]:mt-6 [&_h2]:mb-3 [&_h2:first-child]:mt-0", "[&_h3]:text-xl [&_h3]:font-bold [&_h3]:leading-tight [&_h3]:mt-4 [&_h3]:mb-2 [&_h3:first-child]:mt-0", "[&_p]:mb-3", "[&_ul]:list-disc [&_ul]:pl-6 [&_ul]:mb-3", "[&_ol]:list-decimal [&_ol]:pl-6 [&_ol]:mb-3", "[&_blockquote]:border-l-4 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:mb-4 [&_blockquote]:italic [&_blockquote:first-child]:mt-0", "[&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[0.875em] [&_code]:font-mono", "[&_pre]:bg-muted [&_pre]:p-4 [&_pre]:rounded [&_pre]:overflow-x-auto [&_pre]:font-mono [&_pre]:mb-4", "[&_*:last-child]:mb-0", slots?.content?.className) } }), [slots]);
|
|
35
|
+
const defaultEditorProps = React.useMemo(() => ({ attributes: { class: cn("min-h-[200px] p-4 text-sm leading-relaxed focus:outline-none", "[&_h1]:text-3xl [&_h1]:font-bold [&_h1]:leading-tight [&_h1]:mt-8 [&_h1]:mb-4 [&_h1:first-child]:mt-0", "[&_h2]:text-2xl [&_h2]:font-bold [&_h2]:leading-tight [&_h2]:mt-6 [&_h2]:mb-3 [&_h2:first-child]:mt-0", "[&_h3]:text-xl [&_h3]:font-bold [&_h3]:leading-tight [&_h3]:mt-4 [&_h3]:mb-2 [&_h3:first-child]:mt-0", "[&_p]:mb-3", "[&_ul]:list-disc [&_ul]:pl-6 [&_ul]:mb-3", "[&_ol]:list-decimal [&_ol]:pl-6 [&_ol]:mb-3", "[&_blockquote]:border-l-4 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:mb-4 [&_blockquote]:italic [&_blockquote:first-child]:mt-0", "[&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[0.875em] [&_code]:font-mono", "[&_pre]:bg-muted [&_pre]:p-4 [&_pre]:rounded [&_pre]:overflow-x-auto [&_pre]:font-mono [&_pre]:mb-4", "[&_a]:text-blue-500 [&_a]:hover:text-blue-600 [&_a]:cursor-pointer [&_a]:underline [&_a]:underline-offset-2 ", "[&_*:last-child]:mb-0", slots?.content?.className) } }), [slots]);
|
|
29
36
|
return React.useMemo(() => ({
|
|
30
37
|
...defaultEditorProps,
|
|
31
38
|
...customEditorProps,
|
|
@@ -45,7 +52,11 @@ const RichTextEditor = ({ value, onChange, extensions = defaultExtensions, edita
|
|
|
45
52
|
onChangeRef.current?.(props.editor.getHTML());
|
|
46
53
|
}, []);
|
|
47
54
|
const editorInstance = useEditor({
|
|
48
|
-
extensions:
|
|
55
|
+
extensions: React.useMemo(() => [
|
|
56
|
+
StarterKit,
|
|
57
|
+
Link,
|
|
58
|
+
TextAlign.configure({ types: ["heading", "paragraph"] })
|
|
59
|
+
].concat(extensions), [extensions]),
|
|
49
60
|
content: value,
|
|
50
61
|
editable,
|
|
51
62
|
onUpdate: handleChange,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_svg = require('../utils/svg.cjs');
|
|
2
3
|
let __pixpilot_shadcn = require("@pixpilot/shadcn");
|
|
3
4
|
__pixpilot_shadcn = require_rolldown_runtime.__toESM(__pixpilot_shadcn);
|
|
4
5
|
let react = require("react");
|
|
@@ -7,14 +8,6 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
7
8
|
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
8
9
|
|
|
9
10
|
//#region src/rich-text-editor/ToolbarButton.tsx
|
|
10
|
-
function isSvgMarkupString(value) {
|
|
11
|
-
if (typeof value !== "string") return false;
|
|
12
|
-
const trimmed = value.trim();
|
|
13
|
-
return trimmed.startsWith("<svg") && trimmed.endsWith("</svg>");
|
|
14
|
-
}
|
|
15
|
-
function svgMarkupToMaskUrl(svgMarkup) {
|
|
16
|
-
return `url("data:image/svg+xml,${encodeURIComponent(svgMarkup).replace(/'/gu, "%27").replace(/"/gu, "%22")}")`;
|
|
17
|
-
}
|
|
18
11
|
const ToolbarButton = ({ onClick, isActive, disabled, className, children, tooltip }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Tooltip, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.TooltipTrigger, {
|
|
19
12
|
asChild: true,
|
|
20
13
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
|
|
@@ -27,14 +20,14 @@ const ToolbarButton = ({ onClick, isActive, disabled, className, children, toolt
|
|
|
27
20
|
onClick,
|
|
28
21
|
disabled,
|
|
29
22
|
className: (0, __pixpilot_shadcn.cn)("h-8 w-8 p-0", className),
|
|
30
|
-
children: isSvgMarkupString(children) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
23
|
+
children: require_svg.isSvgMarkupString(children) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
31
24
|
"data-slot": "svg-mask",
|
|
32
25
|
"aria-hidden": "true",
|
|
33
26
|
className: "inline-block h-4 w-4",
|
|
34
27
|
style: {
|
|
35
28
|
backgroundColor: "currentColor",
|
|
36
|
-
WebkitMaskImage: svgMarkupToMaskUrl(children),
|
|
37
|
-
maskImage: svgMarkupToMaskUrl(children),
|
|
29
|
+
WebkitMaskImage: require_svg.svgMarkupToMaskUrl(children),
|
|
30
|
+
maskImage: require_svg.svgMarkupToMaskUrl(children),
|
|
38
31
|
WebkitMaskRepeat: "no-repeat",
|
|
39
32
|
maskRepeat: "no-repeat",
|
|
40
33
|
WebkitMaskPosition: "center",
|
|
@@ -1,16 +1,9 @@
|
|
|
1
|
+
import { isSvgMarkupString, svgMarkupToMaskUrl } from "../utils/svg.js";
|
|
1
2
|
import { Button, Tooltip, TooltipContent, TooltipTrigger, cn } from "@pixpilot/shadcn";
|
|
2
3
|
import React from "react";
|
|
3
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
5
|
|
|
5
6
|
//#region src/rich-text-editor/ToolbarButton.tsx
|
|
6
|
-
function isSvgMarkupString(value) {
|
|
7
|
-
if (typeof value !== "string") return false;
|
|
8
|
-
const trimmed = value.trim();
|
|
9
|
-
return trimmed.startsWith("<svg") && trimmed.endsWith("</svg>");
|
|
10
|
-
}
|
|
11
|
-
function svgMarkupToMaskUrl(svgMarkup) {
|
|
12
|
-
return `url("data:image/svg+xml,${encodeURIComponent(svgMarkup).replace(/'/gu, "%27").replace(/"/gu, "%22")}")`;
|
|
13
|
-
}
|
|
14
7
|
const ToolbarButton = ({ onClick, isActive, disabled, className, children, tooltip }) => /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
15
8
|
asChild: true,
|
|
16
9
|
children: /* @__PURE__ */ jsx(Button, {
|
|
@@ -24,6 +24,12 @@ const predefinedToolbarItems = {
|
|
|
24
24
|
onClick: (editor) => editor.chain().focus().toggleUnderline().run(),
|
|
25
25
|
isActive: (editor) => editor.isActive("underline")
|
|
26
26
|
},
|
|
27
|
+
link: {
|
|
28
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Link, { className: "h-4 w-4" }),
|
|
29
|
+
tooltip: "Link",
|
|
30
|
+
onClick: (editor) => editor.chain().focus().toggleLink().run(),
|
|
31
|
+
isActive: (editor) => editor.isActive("link")
|
|
32
|
+
},
|
|
27
33
|
strike: {
|
|
28
34
|
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Strikethrough, { className: "h-4 w-4" }),
|
|
29
35
|
tooltip: "Strikethrough",
|
|
@@ -77,6 +83,24 @@ const predefinedToolbarItems = {
|
|
|
77
83
|
tooltip: "Code Block",
|
|
78
84
|
onClick: (editor) => editor.chain().focus().toggleCodeBlock().run(),
|
|
79
85
|
isActive: (editor) => editor.isActive("codeBlock")
|
|
86
|
+
},
|
|
87
|
+
alignLeft: {
|
|
88
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.AlignLeft, { className: "h-4 w-4" }),
|
|
89
|
+
tooltip: "Align Left",
|
|
90
|
+
onClick: (editor) => editor.chain().focus().setTextAlign("left").run(),
|
|
91
|
+
isActive: (editor) => editor.isActive({ textAlign: "left" })
|
|
92
|
+
},
|
|
93
|
+
alignCenter: {
|
|
94
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.AlignCenter, { className: "h-4 w-4" }),
|
|
95
|
+
tooltip: "Align Center",
|
|
96
|
+
onClick: (editor) => editor.chain().focus().setTextAlign("center").run(),
|
|
97
|
+
isActive: (editor) => editor.isActive({ textAlign: "center" })
|
|
98
|
+
},
|
|
99
|
+
alignRight: {
|
|
100
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.AlignRight, { className: "h-4 w-4" }),
|
|
101
|
+
tooltip: "Align Right",
|
|
102
|
+
onClick: (editor) => editor.chain().focus().setTextAlign("right").run(),
|
|
103
|
+
isActive: (editor) => editor.isActive({ textAlign: "right" })
|
|
80
104
|
}
|
|
81
105
|
};
|
|
82
106
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Bold, Code, Code2, Heading1, Heading2, Heading3, Italic, List, ListOrdered, Quote, Strikethrough, Underline } from "lucide-react";
|
|
1
|
+
import { AlignCenter, AlignLeft, AlignRight, Bold, Code, Code2, Heading1, Heading2, Heading3, Italic, Link, List, ListOrdered, Quote, Strikethrough, Underline } from "lucide-react";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/rich-text-editor/predefined-toolbar-items.tsx
|
|
@@ -21,6 +21,12 @@ const predefinedToolbarItems = {
|
|
|
21
21
|
onClick: (editor) => editor.chain().focus().toggleUnderline().run(),
|
|
22
22
|
isActive: (editor) => editor.isActive("underline")
|
|
23
23
|
},
|
|
24
|
+
link: {
|
|
25
|
+
icon: /* @__PURE__ */ jsx(Link, { className: "h-4 w-4" }),
|
|
26
|
+
tooltip: "Link",
|
|
27
|
+
onClick: (editor) => editor.chain().focus().toggleLink().run(),
|
|
28
|
+
isActive: (editor) => editor.isActive("link")
|
|
29
|
+
},
|
|
24
30
|
strike: {
|
|
25
31
|
icon: /* @__PURE__ */ jsx(Strikethrough, { className: "h-4 w-4" }),
|
|
26
32
|
tooltip: "Strikethrough",
|
|
@@ -74,6 +80,24 @@ const predefinedToolbarItems = {
|
|
|
74
80
|
tooltip: "Code Block",
|
|
75
81
|
onClick: (editor) => editor.chain().focus().toggleCodeBlock().run(),
|
|
76
82
|
isActive: (editor) => editor.isActive("codeBlock")
|
|
83
|
+
},
|
|
84
|
+
alignLeft: {
|
|
85
|
+
icon: /* @__PURE__ */ jsx(AlignLeft, { className: "h-4 w-4" }),
|
|
86
|
+
tooltip: "Align Left",
|
|
87
|
+
onClick: (editor) => editor.chain().focus().setTextAlign("left").run(),
|
|
88
|
+
isActive: (editor) => editor.isActive({ textAlign: "left" })
|
|
89
|
+
},
|
|
90
|
+
alignCenter: {
|
|
91
|
+
icon: /* @__PURE__ */ jsx(AlignCenter, { className: "h-4 w-4" }),
|
|
92
|
+
tooltip: "Align Center",
|
|
93
|
+
onClick: (editor) => editor.chain().focus().setTextAlign("center").run(),
|
|
94
|
+
isActive: (editor) => editor.isActive({ textAlign: "center" })
|
|
95
|
+
},
|
|
96
|
+
alignRight: {
|
|
97
|
+
icon: /* @__PURE__ */ jsx(AlignRight, { className: "h-4 w-4" }),
|
|
98
|
+
tooltip: "Align Right",
|
|
99
|
+
onClick: (editor) => editor.chain().focus().setTextAlign("right").run(),
|
|
100
|
+
isActive: (editor) => editor.isActive({ textAlign: "right" })
|
|
77
101
|
}
|
|
78
102
|
};
|
|
79
103
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime10 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/theme-toggle/ThemeModeDropdown.d.ts
|
|
4
4
|
interface ThemeModeDropdownProps {
|
|
@@ -17,7 +17,7 @@ interface ThemeModeDropdownProps {
|
|
|
17
17
|
* Provides Light / Dark / System options.
|
|
18
18
|
* Pure component - requires themeValue and onChange props.
|
|
19
19
|
*/
|
|
20
|
-
declare function ThemeModeDropdown(props: ThemeModeDropdownProps):
|
|
20
|
+
declare function ThemeModeDropdown(props: ThemeModeDropdownProps): react_jsx_runtime10.JSX.Element;
|
|
21
21
|
declare namespace ThemeModeDropdown {
|
|
22
22
|
var displayName: string;
|
|
23
23
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime11 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/theme-toggle/ThemeModeSwitchInside.d.ts
|
|
4
4
|
type ThemeModeSwitchInsideSize = 'sm' | 'md' | 'lg';
|
|
@@ -25,7 +25,7 @@ interface ThemeModeSwitchInsideProps {
|
|
|
25
25
|
* Icons are embedded within the switch control.
|
|
26
26
|
* Pure component - requires value and onChange props.
|
|
27
27
|
*/
|
|
28
|
-
declare function ThemeModeSwitchInside(props: ThemeModeSwitchInsideProps):
|
|
28
|
+
declare function ThemeModeSwitchInside(props: ThemeModeSwitchInsideProps): react_jsx_runtime11.JSX.Element;
|
|
29
29
|
declare namespace ThemeModeSwitchInside {
|
|
30
30
|
var displayName: string;
|
|
31
31
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime12 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/theme-toggle/ThemeModeSwitchOutside.d.ts
|
|
4
4
|
interface ThemeModeSwitchOutsideProps {
|
|
@@ -22,7 +22,7 @@ interface ThemeModeSwitchOutsideProps {
|
|
|
22
22
|
* Icons flank the switch control on either side.
|
|
23
23
|
* Pure component - requires value and onChange props.
|
|
24
24
|
*/
|
|
25
|
-
declare function ThemeModeSwitchOutside(props: ThemeModeSwitchOutsideProps):
|
|
25
|
+
declare function ThemeModeSwitchOutside(props: ThemeModeSwitchOutsideProps): react_jsx_runtime12.JSX.Element;
|
|
26
26
|
declare namespace ThemeModeSwitchOutside {
|
|
27
27
|
var displayName: string;
|
|
28
28
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime9 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/theme-toggle/ThemeModeToggleButton.d.ts
|
|
4
4
|
interface ThemeModeToggleButtonProps {
|
|
@@ -13,7 +13,7 @@ interface ThemeModeToggleButtonProps {
|
|
|
13
13
|
* Light/Dark toggle button.
|
|
14
14
|
* Pure component - toggles between light and dark.
|
|
15
15
|
*/
|
|
16
|
-
declare function ThemeModeToggleButton(props: ThemeModeToggleButtonProps):
|
|
16
|
+
declare function ThemeModeToggleButton(props: ThemeModeToggleButtonProps): react_jsx_runtime9.JSX.Element;
|
|
17
17
|
declare namespace ThemeModeToggleButton {
|
|
18
18
|
var displayName: string;
|
|
19
19
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/utils/svg.ts
|
|
3
|
+
/**
|
|
4
|
+
* Checks if a value is an SVG markup string
|
|
5
|
+
* @param value - The value to check
|
|
6
|
+
* @returns True if the value is a string starting with '<svg' and ending with '</svg>'
|
|
7
|
+
*/
|
|
8
|
+
function isSvgMarkupString(value) {
|
|
9
|
+
if (typeof value !== "string") return false;
|
|
10
|
+
const trimmed = value.trim();
|
|
11
|
+
return trimmed.startsWith("<svg") && trimmed.endsWith("</svg>");
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Converts SVG markup string to a CSS mask-image data URL
|
|
15
|
+
* Useful for rendering SVG strings as masked icons that inherit currentColor
|
|
16
|
+
* @param svgMarkup - The SVG markup string
|
|
17
|
+
* @returns A CSS url() value for use in mask-image properties
|
|
18
|
+
*/
|
|
19
|
+
function svgMarkupToMaskUrl(svgMarkup) {
|
|
20
|
+
return `url("data:image/svg+xml,${encodeURIComponent(svgMarkup).replace(/'/gu, "%27").replace(/"/gu, "%22")}")`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
exports.isSvgMarkupString = isSvgMarkupString;
|
|
25
|
+
exports.svgMarkupToMaskUrl = svgMarkupToMaskUrl;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/utils/svg.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Checks if a value is an SVG markup string
|
|
4
|
+
* @param value - The value to check
|
|
5
|
+
* @returns True if the value is a string starting with '<svg' and ending with '</svg>'
|
|
6
|
+
*/
|
|
7
|
+
declare function isSvgMarkupString(value: unknown): value is string;
|
|
8
|
+
/**
|
|
9
|
+
* Converts SVG markup string to a CSS mask-image data URL
|
|
10
|
+
* Useful for rendering SVG strings as masked icons that inherit currentColor
|
|
11
|
+
* @param svgMarkup - The SVG markup string
|
|
12
|
+
* @returns A CSS url() value for use in mask-image properties
|
|
13
|
+
*/
|
|
14
|
+
declare function svgMarkupToMaskUrl(svgMarkup: string): string;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { isSvgMarkupString, svgMarkupToMaskUrl };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/utils/svg.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Checks if a value is an SVG markup string
|
|
4
|
+
* @param value - The value to check
|
|
5
|
+
* @returns True if the value is a string starting with '<svg' and ending with '</svg>'
|
|
6
|
+
*/
|
|
7
|
+
declare function isSvgMarkupString(value: unknown): value is string;
|
|
8
|
+
/**
|
|
9
|
+
* Converts SVG markup string to a CSS mask-image data URL
|
|
10
|
+
* Useful for rendering SVG strings as masked icons that inherit currentColor
|
|
11
|
+
* @param svgMarkup - The SVG markup string
|
|
12
|
+
* @returns A CSS url() value for use in mask-image properties
|
|
13
|
+
*/
|
|
14
|
+
declare function svgMarkupToMaskUrl(svgMarkup: string): string;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { isSvgMarkupString, svgMarkupToMaskUrl };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/utils/svg.ts
|
|
2
|
+
/**
|
|
3
|
+
* Checks if a value is an SVG markup string
|
|
4
|
+
* @param value - The value to check
|
|
5
|
+
* @returns True if the value is a string starting with '<svg' and ending with '</svg>'
|
|
6
|
+
*/
|
|
7
|
+
function isSvgMarkupString(value) {
|
|
8
|
+
if (typeof value !== "string") return false;
|
|
9
|
+
const trimmed = value.trim();
|
|
10
|
+
return trimmed.startsWith("<svg") && trimmed.endsWith("</svg>");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Converts SVG markup string to a CSS mask-image data URL
|
|
14
|
+
* Useful for rendering SVG strings as masked icons that inherit currentColor
|
|
15
|
+
* @param svgMarkup - The SVG markup string
|
|
16
|
+
* @returns A CSS url() value for use in mask-image properties
|
|
17
|
+
*/
|
|
18
|
+
function svgMarkupToMaskUrl(svgMarkup) {
|
|
19
|
+
return `url("data:image/svg+xml,${encodeURIComponent(svgMarkup).replace(/'/gu, "%27").replace(/"/gu, "%22")}")`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { isSvgMarkupString, svgMarkupToMaskUrl };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixpilot/shadcn-ui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.37.0",
|
|
5
5
|
"description": "Custom UI components and utilities built with shadcn/ui.",
|
|
6
6
|
"author": "m.doaie <m.doaie@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -34,10 +34,12 @@
|
|
|
34
34
|
"@iconify/react": "^6.0.2",
|
|
35
35
|
"@pixpilot/hash": "^0.0.0",
|
|
36
36
|
"@tailwindcss/typography": "^0.5.19",
|
|
37
|
-
"@tanstack/react-virtual": "^3.13.
|
|
38
|
-
"@tiptap/core": "^3.
|
|
39
|
-
"@tiptap/
|
|
40
|
-
"@tiptap/
|
|
37
|
+
"@tanstack/react-virtual": "^3.13.18",
|
|
38
|
+
"@tiptap/core": "^3.16.0",
|
|
39
|
+
"@tiptap/extension-link": "^3.16.0",
|
|
40
|
+
"@tiptap/extension-text-align": "^3.16.0",
|
|
41
|
+
"@tiptap/react": "^3.16.0",
|
|
42
|
+
"@tiptap/starter-kit": "^3.16.0",
|
|
41
43
|
"class-variance-authority": "^0.7.1",
|
|
42
44
|
"lucide-react": "0.553.0",
|
|
43
45
|
"next-themes": "0.4.6",
|
|
@@ -57,9 +59,9 @@
|
|
|
57
59
|
"react-dom": "19.2.0",
|
|
58
60
|
"tsdown": "^0.15.12",
|
|
59
61
|
"typescript": "^5.9.3",
|
|
62
|
+
"@internal/eslint-config": "0.3.0",
|
|
60
63
|
"@internal/hooks": "0.0.0",
|
|
61
64
|
"@internal/prettier-config": "0.0.1",
|
|
62
|
-
"@internal/eslint-config": "0.3.0",
|
|
63
65
|
"@internal/tsconfig": "0.1.0",
|
|
64
66
|
"@internal/tsdown-config": "0.1.0",
|
|
65
67
|
"@internal/vitest-config": "0.1.0"
|