pixedi 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +65 -60
  2. package/README.npm.md +80 -0
  3. package/dist/lib/index.js +1602 -0
  4. package/dist/lib/index.umd.js +28 -0
  5. package/package.json +9 -4
  6. package/.github/workflows/deploy.yml +0 -54
  7. package/.prettierr +0 -9
  8. package/.storybook/main.ts +0 -16
  9. package/.storybook/preview.ts +0 -53
  10. package/.vscode/extensions.json +0 -6
  11. package/eslint.config.js +0 -22
  12. package/index.html +0 -13
  13. package/pnpm-workspace.yaml +0 -2
  14. package/public/favicon.svg +0 -1
  15. package/src/app/App.tsx +0 -10
  16. package/src/app/entries/index.ts +0 -145
  17. package/src/app/providers/RouterProvider.tsx +0 -6
  18. package/src/app/providers/index.ts +0 -1
  19. package/src/app/router/AppRouter.tsx +0 -12
  20. package/src/app/router/index.ts +0 -0
  21. package/src/app/styles/index.css +0 -4
  22. package/src/features/gallery/GalleryPage.tsx +0 -33
  23. package/src/features/gallery/ImageEditPage.tsx +0 -37
  24. package/src/features/gallery/index.ts +0 -2
  25. package/src/main.tsx +0 -10
  26. package/src/shared/components/ImageCard/ImageCard.tsx +0 -54
  27. package/src/shared/components/ImageCard/index.ts +0 -1
  28. package/src/shared/components/ImageEditor/ImageEditor.tsx +0 -48
  29. package/src/shared/components/ImageEditor/assets/icons.tsx +0 -114
  30. package/src/shared/components/ImageEditor/constants.ts +0 -118
  31. package/src/shared/components/ImageEditor/crop/Crop.tsx +0 -60
  32. package/src/shared/components/ImageEditor/crop/CropBorders.tsx +0 -28
  33. package/src/shared/components/ImageEditor/crop/CropLines.tsx +0 -8
  34. package/src/shared/components/ImageEditor/crop/CropPointer.tsx +0 -21
  35. package/src/shared/components/ImageEditor/crop/CropPointers.tsx +0 -44
  36. package/src/shared/components/ImageEditor/crop/CropTools.tsx +0 -138
  37. package/src/shared/components/ImageEditor/crop/crop.css +0 -180
  38. package/src/shared/components/ImageEditor/crop/index.ts +0 -8
  39. package/src/shared/components/ImageEditor/crop/useCropInteraction.ts +0 -230
  40. package/src/shared/components/ImageEditor/eventBus.ts +0 -8
  41. package/src/shared/components/ImageEditor/frame/Frame.tsx +0 -48
  42. package/src/shared/components/ImageEditor/frame/frame.css +0 -40
  43. package/src/shared/components/ImageEditor/frame/index.ts +0 -1
  44. package/src/shared/components/ImageEditor/header/Header.tsx +0 -81
  45. package/src/shared/components/ImageEditor/header/header.css +0 -27
  46. package/src/shared/components/ImageEditor/header/index.ts +0 -1
  47. package/src/shared/components/ImageEditor/hooks/index.ts +0 -5
  48. package/src/shared/components/ImageEditor/hooks/useAbove.tsx +0 -18
  49. package/src/shared/components/ImageEditor/hooks/useBellow.tsx +0 -18
  50. package/src/shared/components/ImageEditor/hooks/useImageLoader.tsx +0 -110
  51. package/src/shared/components/ImageEditor/hooks/useImageProcessor.test.tsx +0 -147
  52. package/src/shared/components/ImageEditor/hooks/useImageProcessor.ts +0 -225
  53. package/src/shared/components/ImageEditor/hooks/useMobile.tsx +0 -33
  54. package/src/shared/components/ImageEditor/index.css +0 -145
  55. package/src/shared/components/ImageEditor/index.ts +0 -1
  56. package/src/shared/components/ImageEditor/provider/ImageEditorProvider.test.tsx +0 -126
  57. package/src/shared/components/ImageEditor/provider/ImageEditorProvider.tsx +0 -107
  58. package/src/shared/components/ImageEditor/provider/StoreContext.tsx +0 -20
  59. package/src/shared/components/ImageEditor/provider/initialState.ts +0 -30
  60. package/src/shared/components/ImageEditor/provider/useImageEditorContext.tsx +0 -12
  61. package/src/shared/components/ImageEditor/resize/ResizeTools.tsx +0 -183
  62. package/src/shared/components/ImageEditor/resize/index.ts +0 -1
  63. package/src/shared/components/ImageEditor/resize/resize.css +0 -56
  64. package/src/shared/components/ImageEditor/sidebar/Sidebar.tsx +0 -54
  65. package/src/shared/components/ImageEditor/sidebar/SidebarCrop.tsx +0 -57
  66. package/src/shared/components/ImageEditor/sidebar/SidebarPresets.tsx +0 -54
  67. package/src/shared/components/ImageEditor/sidebar/SidebarResize.tsx +0 -26
  68. package/src/shared/components/ImageEditor/sidebar/index.ts +0 -1
  69. package/src/shared/components/ImageEditor/sidebar/sidebar.css +0 -101
  70. package/src/shared/components/ImageEditor/types.ts +0 -59
  71. package/src/shared/components/ImageEditor/ui/button/Button.stories.tsx +0 -42
  72. package/src/shared/components/ImageEditor/ui/button/Button.tsx +0 -21
  73. package/src/shared/components/ImageEditor/ui/button/button.css +0 -69
  74. package/src/shared/components/ImageEditor/ui/button-crop/ButtonCrop.stories.tsx +0 -26
  75. package/src/shared/components/ImageEditor/ui/button-crop/ButtonCrop.tsx +0 -29
  76. package/src/shared/components/ImageEditor/ui/button-crop/button-crop.css +0 -38
  77. package/src/shared/components/ImageEditor/ui/index.ts +0 -6
  78. package/src/shared/components/ImageEditor/ui/input/Input.stories.tsx +0 -45
  79. package/src/shared/components/ImageEditor/ui/input/Input.tsx +0 -20
  80. package/src/shared/components/ImageEditor/ui/input/input.css +0 -48
  81. package/src/shared/components/ImageEditor/ui/input-pixel/InputPixel.stories.tsx +0 -33
  82. package/src/shared/components/ImageEditor/ui/input-pixel/InputPixel.tsx +0 -23
  83. package/src/shared/components/ImageEditor/ui/input-pixel/input-pixel.css +0 -24
  84. package/src/shared/components/ImageEditor/ui/select/Select.stories.tsx +0 -67
  85. package/src/shared/components/ImageEditor/ui/select/Select.tsx +0 -161
  86. package/src/shared/components/ImageEditor/ui/select/select.css +0 -147
  87. package/src/shared/components/ImageEditor/ui/separator/Separator.stories.tsx +0 -37
  88. package/src/shared/components/ImageEditor/ui/separator/Separator.tsx +0 -27
  89. package/src/shared/components/ImageEditor/ui/separator/separator.css +0 -19
  90. package/src/shared/components/ImageEditor/utils.test.ts +0 -136
  91. package/src/shared/components/ImageEditor/utils.ts +0 -497
  92. package/src/shared/components/ui/index.ts +0 -1
  93. package/src/shared/components/ui/preloader.tsx +0 -78
  94. package/src/shared/config/index.ts +0 -3
  95. package/src/shared/config/routes.ts +0 -4
  96. package/src/shared/features/gallery/GalleryPage.tsx +0 -33
  97. package/src/shared/features/gallery/ImageEditPage.tsx +0 -37
  98. package/src/shared/features/gallery/index.ts +0 -2
  99. package/src/shared/hooks/index.ts +0 -1
  100. package/src/shared/hooks/useImagePreload.tsx +0 -49
  101. package/src/shared/types/index.ts +0 -11
  102. package/src/test/setup.ts +0 -14
  103. package/src/virtual-css-injected-by-js.d.ts +0 -8
  104. package/src/widget.tsx +0 -119
  105. package/tsconfig.app.json +0 -29
  106. package/tsconfig.json +0 -12
  107. package/tsconfig.lib.json +0 -18
  108. package/tsconfig.node.json +0 -23
  109. package/vite-env.d.ts +0 -1
  110. package/vite.config.ts +0 -24
  111. package/vite.lib.config.ts +0 -33
  112. package/vite.widget.config.ts +0 -39
  113. package/wrangler.json +0 -5
@@ -1,54 +0,0 @@
1
- import { useBellow } from "../hooks";
2
- import { Settings, X } from "../assets/icons";
3
- import { Button, Separator } from "../ui";
4
- import { SidebarResize } from "./SidebarResize";
5
- import { SidebarCrop } from "./SidebarCrop";
6
- import { SidebarPresets } from "./SidebarPresets";
7
- import { useImageEditorContext } from "../provider/useImageEditorContext";
8
- import "./sidebar.css";
9
-
10
- export const Sidebar = () => {
11
- const { getSidebar, setSidebar } = useImageEditorContext();
12
- const isSidebarOpen = getSidebar();
13
- const isBellowMd = useBellow("md");
14
-
15
- return (
16
- <>
17
- <Button
18
- variant="outline"
19
- className="sidebar-settings"
20
- onClick={() => setSidebar(true)}
21
- >
22
- <Settings />
23
- </Button>
24
- <div
25
- className="sidebar"
26
- style={{
27
- transform:
28
- isBellowMd && isSidebarOpen
29
- ? "translateX(-320px)"
30
- : "translateX(0%)",
31
- }}
32
- >
33
- <div className="sidebar-container">
34
- <div className="sidebar-content">
35
- {isBellowMd && (
36
- <Button
37
- variant="ghost"
38
- className="sidebar-close-btn btn-rect"
39
- onClick={() => setSidebar(false)}
40
- >
41
- <X />
42
- </Button>
43
- )}
44
- <SidebarResize />
45
- <Separator className="sidebar-separator" />
46
- <SidebarCrop />
47
- <Separator className="sidebar-separator" />
48
- <SidebarPresets />
49
- </div>
50
- </div>
51
- </div>
52
- </>
53
- );
54
- };
@@ -1,57 +0,0 @@
1
- import { Crop, Image, Square } from "../assets/icons";
2
- import { useImageEditorContext } from "../provider/useImageEditorContext";
3
- import type { ActionCrop } from "../types";
4
- import { ButtonCrop } from "../ui";
5
-
6
- export const SidebarCrop = () => {
7
- const { currentAction, setCurrentAction, getLastHistoryItem, setSidebar } =
8
- useImageEditorContext();
9
- const { name, args } = currentAction || {};
10
- const currentValue = name === "crop" ? (args?.id as string) : "";
11
- const { width, height } = getLastHistoryItem();
12
- const originRatio = width / height;
13
-
14
- const handleClick = (value: string) => {
15
- if (value === currentValue) {
16
- return;
17
- }
18
-
19
- const ratio = value === "1:1" ? 1 : originRatio;
20
-
21
- const args: ActionCrop = {
22
- id: value,
23
- ratio,
24
- isFree: value === "freeform",
25
- preset: null,
26
- };
27
-
28
- setCurrentAction({ name: "crop", args });
29
- setSidebar(false);
30
- };
31
-
32
- return (
33
- <div className="sidebar-crop">
34
- <h4>Crop</h4>
35
- <div className="sidebar-crop-ratios">
36
- <ButtonCrop
37
- label="Freeform"
38
- icon={<Crop />}
39
- active={currentValue === "freeform"}
40
- onClick={() => handleClick("freeform")}
41
- />
42
- <ButtonCrop
43
- label="Original"
44
- icon={<Image />}
45
- active={currentValue === "original"}
46
- onClick={() => handleClick("original")}
47
- />
48
- <ButtonCrop
49
- label="1:1"
50
- icon={<Square />}
51
- active={currentValue === "1:1"}
52
- onClick={() => handleClick("1:1")}
53
- />
54
- </div>
55
- </div>
56
- );
57
- };
@@ -1,54 +0,0 @@
1
- import { useImageEditorContext } from "../provider/useImageEditorContext";
2
- import { presetsData } from "../constants";
3
- import type { ActionCrop } from "../types";
4
- import { Select } from "../ui";
5
-
6
- const presetOptions = presetsData.map((p) => p.options).flat();
7
-
8
- export const SidebarPresets = () => {
9
- const { setCurrentAction, currentAction, setSidebar } =
10
- useImageEditorContext();
11
- const currentValue =
12
- currentAction?.name === "crop" &&
13
- presetOptions.some((preset) => preset.value === currentAction.args.id)
14
- ? currentAction.args.id
15
- : "";
16
-
17
- const handleChange = (value: string | null) => {
18
- if (!value) {
19
- return;
20
- }
21
-
22
- const flattenedData = presetsData.map((p) => p.options).flat();
23
- const option = flattenedData.find((po) => po.value === value);
24
- if (!option) {
25
- return;
26
- }
27
-
28
- const ratio = option.w / option.h;
29
-
30
- const args: ActionCrop = {
31
- id: value,
32
- ratio,
33
- isFree: false,
34
- preset: { w: option.w, h: option.h },
35
- };
36
-
37
- setCurrentAction({ name: "crop", args });
38
- setSidebar(false);
39
- };
40
-
41
- return (
42
- <div className="sidebar-preset">
43
- <h4>Presets</h4>
44
- <div className="relative">
45
- <Select
46
- value={currentValue}
47
- placeholder="Select a preset"
48
- onChange={handleChange}
49
- items={presetsData}
50
- />
51
- </div>
52
- </div>
53
- );
54
- };
@@ -1,26 +0,0 @@
1
- import { Fullscreen } from "../assets/icons";
2
- import { useImageEditorContext } from "../provider/useImageEditorContext";
3
- import { Button } from "../ui";
4
-
5
- export const SidebarResize = () => {
6
- const { getLastHistoryItem, setCurrentAction, setSidebar } =
7
- useImageEditorContext();
8
- const { width, height } = getLastHistoryItem() ?? { width: 0, height: 0 };
9
-
10
- const handleClick = () => {
11
- setCurrentAction({ name: "resize", args: { width, height } });
12
- setSidebar(false);
13
- };
14
-
15
- return (
16
- <Button variant="outline" className="sidebar-resize" onClick={handleClick}>
17
- <div className="sidebar-resize-icon">
18
- <Fullscreen />
19
- Resize
20
- </div>
21
- <div className="sidebar-resize-size">
22
- {width} x {height}
23
- </div>
24
- </Button>
25
- );
26
- };
@@ -1 +0,0 @@
1
- export { Sidebar } from "./Sidebar";
@@ -1,101 +0,0 @@
1
- .sidebar {
2
- position: relative;
3
- width: 0;
4
- z-index: 10;
5
- transition: transform 0.15s ease-out;
6
-
7
- @media (min-width: 768px) {
8
- width: 320px;
9
- transition: none;
10
- }
11
- }
12
-
13
- .sidebar-settings {
14
- position: absolute;
15
- top: 8px;
16
- right: 8px;
17
- width: 40px;
18
- height: 40px;
19
- border-radius: 50%;
20
- box-shadow:
21
- 0 20px 25px -5px rgba(0, 0, 0, 0.1),
22
- 0 8px 10px -6px rgba(0, 0, 0, 0.1);
23
-
24
- @media (min-width: 768px) {
25
- display: none;
26
- }
27
- }
28
-
29
- .sidebar-container {
30
- position: absolute;
31
- top: 0;
32
- right: 0;
33
- bottom: 0;
34
- left: 0;
35
- box-sizing: border-box;
36
- border-left: 1px solid var(--border);
37
- }
38
-
39
- .sidebar-content {
40
- position: absolute;
41
- top: 0;
42
- left: 0;
43
- height: 100%;
44
- width: 320px;
45
- display: flex;
46
- flex-direction: column;
47
- overflow-y: auto;
48
- background-color: var(--background);
49
- padding: 16px;
50
- box-sizing: border-box;
51
-
52
- @media (max-width: 767px) {
53
- padding-top: 48px;
54
- }
55
- }
56
-
57
- .sidebar-close-btn {
58
- position: absolute;
59
- top: 8px;
60
- right: 8px;
61
- }
62
-
63
- .sidebar-separator {
64
- margin-top: 20px;
65
- margin-bottom: 12px;
66
- }
67
-
68
- .sidebar-resize {
69
- display: flex;
70
- align-items: center;
71
- justify-content: space-between;
72
- }
73
-
74
- .sidebar-resize-icon {
75
- display: flex;
76
- align-items: center;
77
- gap: 8px;
78
- }
79
-
80
- .sidebar-resize-size {
81
- font-size: 14px;
82
- color: var(--muted-foreground);
83
- }
84
-
85
- .sidebar-crop {
86
- display: flex;
87
- flex-direction: column;
88
- gap: 8px;
89
- }
90
-
91
- .sidebar-crop-ratios {
92
- display: grid;
93
- grid-template-columns: repeat(3, 1fr);
94
- gap: 8px;
95
- }
96
-
97
- .sidebar-preset {
98
- display: flex;
99
- flex-direction: column;
100
- gap: 8px;
101
- }
@@ -1,59 +0,0 @@
1
- export const breakpoints = {
2
- sm: 640,
3
- md: 768,
4
- lg: 1024,
5
- xl: 1280,
6
- } as const;
7
-
8
- export type Breakpoint = keyof typeof breakpoints;
9
-
10
- export type Sizes = {
11
- width: number;
12
- height: number;
13
- };
14
-
15
- export type Direction = "r" | "l" | "t" | "b" | "tl" | "tr" | "bl" | "br";
16
-
17
- export type CropSizes = {
18
- w: number;
19
- h: number;
20
- };
21
-
22
- export type CropRect = CropSizes & {
23
- x: number;
24
- y: number;
25
- xPx?: number;
26
- yPx?: number;
27
- wPx?: number;
28
- hPx?: number;
29
- };
30
-
31
- export type ActionCrop = {
32
- id: string;
33
- ratio: number;
34
- isFree: boolean;
35
- preset: CropSizes | null;
36
- };
37
-
38
- export type ActionWithVal = {
39
- val: number;
40
- };
41
-
42
- export type Action =
43
- | { name: "resize"; args: Sizes }
44
- | { name: "crop"; args: ActionCrop }
45
- | { name: "flipH"; args: ActionWithVal }
46
- | { name: "flipV"; args: ActionWithVal }
47
- | { name: "filters"; args: Record<string, number> };
48
-
49
- export type HistoryItem = Sizes & {
50
- name: string;
51
- base64: string;
52
- };
53
-
54
- export type History = {
55
- pointer: number;
56
- items: Array<HistoryItem>;
57
- };
58
-
59
- export type FuncSaveArgs = (base64: string) => Promise<void> | void;
@@ -1,42 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react";
2
- import { fn } from "@storybook/test";
3
- import { Button } from "./Button";
4
- import { Check } from "../../assets/icons";
5
-
6
- const meta = {
7
- title: "ImageEditor/UI/Button",
8
- component: Button,
9
- tags: ["autodocs"],
10
- args: {
11
- children: "Button",
12
- onClick: fn(),
13
- },
14
- } satisfies Meta<typeof Button>;
15
-
16
- export default meta;
17
- type Story = StoryObj<typeof meta>;
18
-
19
- export const Default: Story = {};
20
-
21
- export const Outline: Story = {
22
- args: {
23
- variant: "outline",
24
- },
25
- };
26
-
27
- export const Ghost: Story = {
28
- args: {
29
- variant: "ghost",
30
- },
31
- };
32
-
33
- export const WithIcon: Story = {
34
- args: {
35
- children: (
36
- <>
37
- <Check />
38
- Button
39
- </>
40
- ),
41
- },
42
- };
@@ -1,21 +0,0 @@
1
- import { forwardRef } from "react";
2
- import "./button.css";
3
-
4
- interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
5
- variant?: "default" | "outline" | "ghost";
6
- className?: string;
7
- children?: React.ReactNode;
8
- }
9
-
10
- export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
11
- ({ className = "", variant = "default", children, ...props }, ref) => {
12
- const variantClass = `btn-${variant}`;
13
- const combinedClasses = `btn ${variantClass} ${className}`.trim();
14
-
15
- return (
16
- <button ref={ref} className={combinedClasses} {...props}>
17
- {children}
18
- </button>
19
- );
20
- },
21
- );
@@ -1,69 +0,0 @@
1
- .btn {
2
- display: inline-flex;
3
- align-items: center;
4
- justify-content: center;
5
- gap: 8px;
6
- font-family: inherit;
7
- font-size: 14px;
8
- font-weight: 500;
9
- height: 32px;
10
- padding-left: 8px;
11
- padding-right: 8px;
12
- border-radius: 4px;
13
- border: 1px solid transparent;
14
- background-color: transparent;
15
- cursor: pointer;
16
- white-space: nowrap;
17
- user-select: none;
18
- box-sizing: border-box;
19
- transition:
20
- background-color 0.2s,
21
- border-color 0.2s,
22
- opacity 0.2s;
23
- }
24
-
25
- .btn:disabled {
26
- pointer-events: none;
27
- opacity: 0.5;
28
- }
29
-
30
- .btn:active {
31
- transform: translateY(1px);
32
- }
33
-
34
- .btn svg {
35
- width: 16px;
36
- height: 16px;
37
- flex-shrink: 0;
38
- }
39
-
40
- .btn-default {
41
- background-color: var(--primary);
42
- color: var(--primary-foreground);
43
- }
44
- .btn-default:hover {
45
- opacity: 0.9;
46
- }
47
-
48
- .btn-outline {
49
- border-color: var(--border);
50
- background-color: var(--background);
51
- color: var(--foreground);
52
- }
53
- .btn-outline:hover {
54
- background-color: var(--secondary);
55
- }
56
-
57
- .btn-ghost {
58
- color: var(--foreground);
59
- padding-left: 8px;
60
- padding-right: 8px;
61
- }
62
- .btn-ghost:hover {
63
- background-color: var(--secondary);
64
- }
65
-
66
- .btn-rect {
67
- width: 32px;
68
- height: 32px;
69
- }
@@ -1,26 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react";
2
- import { fn } from "@storybook/test";
3
- import { ButtonCrop } from "./ButtonCrop";
4
- import { Crop } from "../../assets/icons";
5
-
6
- const meta = {
7
- title: "ImageEditor/UI/ButtonCrop",
8
- component: ButtonCrop,
9
- tags: ["autodocs"],
10
- args: {
11
- icon: <Crop />,
12
- label: "Crop",
13
- onClick: fn(),
14
- },
15
- } satisfies Meta<typeof ButtonCrop>;
16
-
17
- export default meta;
18
- type Story = StoryObj<typeof meta>;
19
-
20
- export const Inactive: Story = {};
21
-
22
- export const Active: Story = {
23
- args: {
24
- active: true,
25
- },
26
- };
@@ -1,29 +0,0 @@
1
- import { forwardRef } from "react";
2
- import "./button-crop.css";
3
-
4
- interface ButtonCropProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
5
- active?: boolean;
6
- icon: React.ReactNode;
7
- label: string;
8
- }
9
-
10
- export const ButtonCrop = forwardRef<HTMLButtonElement, ButtonCropProps>(
11
- ({ className = "", active = false, icon, label, ...props }, ref) => {
12
- const combinedClasses = `btn-crop ${className}`.trim();
13
-
14
- return (
15
- <button
16
- ref={ref}
17
- type="button"
18
- aria-pressed={active}
19
- className={combinedClasses}
20
- {...props}
21
- >
22
- {icon}
23
- <span className="semibold">{label}</span>
24
- </button>
25
- );
26
- },
27
- );
28
-
29
- ButtonCrop.displayName = "ButtonCrop";
@@ -1,38 +0,0 @@
1
- .btn-crop {
2
- display: inline-flex;
3
- flex-direction: column;
4
- align-items: center;
5
- justify-content: center;
6
- gap: 8px;
7
- padding: 12px;
8
- border-radius: 4px;
9
- border: 1px solid var(--border);
10
- background-color: var(--background);
11
- color: var(--foreground);
12
- font-family: inherit;
13
- font-size: 12px;
14
- cursor: pointer;
15
- user-select: none;
16
- box-sizing: border-box;
17
- transition: all 0.2s ease;
18
- }
19
-
20
- .btn-crop:hover:not([aria-pressed="true"]) {
21
- background-color: var(--secondary);
22
- }
23
-
24
- .btn-crop[aria-pressed="true"] {
25
- border-color: var(--accent-blue);
26
- background-color: var(--accent-blue-light);
27
- color: var(--foreground);
28
- }
29
-
30
- .btn-crop svg {
31
- width: 20px;
32
- height: 20px;
33
- flex-shrink: 0;
34
- }
35
-
36
- .btn-crop span {
37
- white-space: nowrap;
38
- }
@@ -1,6 +0,0 @@
1
- export { Button } from "./button/Button";
2
- export { ButtonCrop } from "./button-crop/ButtonCrop";
3
- export { Separator } from "./separator/Separator";
4
- export { Select } from "./select/Select";
5
- export { Input } from "./input/Input";
6
- export { InputPixel } from "./input-pixel/InputPixel";
@@ -1,45 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react";
2
- import { fn } from "@storybook/test";
3
- import { Input } from "./Input";
4
-
5
- const meta = {
6
- title: "ImageEditor/UI/Input",
7
- component: Input,
8
- tags: ["autodocs"],
9
- args: {
10
- placeholder: "Type here...",
11
- onChange: fn(),
12
- },
13
- decorators: [
14
- (Story) => (
15
- <div style={{ maxWidth: 320 }}>
16
- <Story />
17
- </div>
18
- ),
19
- ],
20
- } satisfies Meta<typeof Input>;
21
-
22
- export default meta;
23
- type Story = StoryObj<typeof meta>;
24
-
25
- export const Text: Story = {
26
- args: {
27
- type: "text",
28
- value: "Sample text",
29
- },
30
- };
31
-
32
- export const Number: Story = {
33
- args: {
34
- type: "number",
35
- value: 42,
36
- },
37
- };
38
-
39
- export const NumberWithArrows: Story = {
40
- args: {
41
- type: "number",
42
- hideArrows: false,
43
- value: 42,
44
- },
45
- };
@@ -1,20 +0,0 @@
1
- import { forwardRef } from "react";
2
- import "./input.css";
3
-
4
- export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
5
- hideArrows?: boolean;
6
- }
7
-
8
- export const Input = forwardRef<HTMLInputElement, InputProps>(
9
- ({ className = "", type = "text", hideArrows = true, ...props }, ref) => {
10
- const numberClass =
11
- type === "number" && hideArrows ? "input-number-clean" : "";
12
- const combinedClasses = `input ${numberClass} ${className}`.trim();
13
-
14
- return (
15
- <input ref={ref} type={type} className={combinedClasses} {...props} />
16
- );
17
- },
18
- );
19
-
20
- Input.displayName = "Input";