@octanejs/image-crop 0.0.1
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/LICENSE +7 -0
- package/README.md +33 -0
- package/UPSTREAM.md +45 -0
- package/package.json +54 -0
- package/src/ReactCrop.css +1 -0
- package/src/ReactCrop.tsrx +918 -0
- package/src/addons/browserCrop.ts +84 -0
- package/src/index.ts +7 -0
- package/src/types.ts +20 -0
- package/src/utils.ts +347 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
## ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015, Dominic Tobias (https://github.com/dominictobias)
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @octanejs/image-crop
|
|
2
|
+
|
|
3
|
+
The Octane port of `react-image-crop@11.1.2`.
|
|
4
|
+
|
|
5
|
+
```tsrx
|
|
6
|
+
import { useState } from 'octane';
|
|
7
|
+
import ReactCrop, { type Crop } from '@octanejs/image-crop';
|
|
8
|
+
import '@octanejs/image-crop/ReactCrop.css';
|
|
9
|
+
|
|
10
|
+
export function AvatarCrop() @{
|
|
11
|
+
const [crop, setCrop] = useState<Crop>({
|
|
12
|
+
unit: '%',
|
|
13
|
+
x: 10,
|
|
14
|
+
y: 10,
|
|
15
|
+
width: 80,
|
|
16
|
+
height: 80,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
<ReactCrop crop={crop} onChange={(_pixels, percentage) => setCrop(percentage)}>
|
|
20
|
+
<img src="/avatar.jpg" alt="Choose an avatar crop" />
|
|
21
|
+
</ReactCrop>
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The component preserves the pinned release's controlled crop API, resize and drag constraints, keyboard nudging, aspect handling, circular crop mask, rule-of-thirds overlay, selection addon, utilities, and legacy `Component` alias.
|
|
26
|
+
|
|
27
|
+
Octane handlers use native `PointerEvent` and `KeyboardEvent` objects. The public crop update callback remains named `onChange`.
|
|
28
|
+
|
|
29
|
+
See [UPSTREAM.md](./UPSTREAM.md) for the immutable source pin, npm integrity, export crosswalk, and upstream test inventory.
|
|
30
|
+
|
|
31
|
+
## License
|
|
32
|
+
|
|
33
|
+
ISC. The upstream copyright and permission notice are retained in [LICENSE](./LICENSE).
|
package/UPSTREAM.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Upstream provenance
|
|
2
|
+
|
|
3
|
+
- Repository: <https://github.com/dominictobias/react-image-crop>
|
|
4
|
+
- Package/version: `react-image-crop@11.1.2`
|
|
5
|
+
- Commit: `2cd4d49b36ec9a29a63b27394ec29ade5646dc99`
|
|
6
|
+
- License: ISC
|
|
7
|
+
- npm integrity: `sha512-+0Pc2fxpwKL4u4oLmdKBw8XSwUceFbXbKEHvFOlsl/MGB1OVNic4uBlAPmEHGXYgoJIq+b63xHbc/aJMG0AVkA==`
|
|
8
|
+
- Advertised compatibility target: exactly `11.1.2`
|
|
9
|
+
|
|
10
|
+
## Source boundary
|
|
11
|
+
|
|
12
|
+
`upstream/src/` is the byte-exact canonical repository source at the pinned commit. `upstream/npm/` records the published npm source payload, while `upstream-artifact/ReactCrop.css` records the generated stylesheet from the pinned npm tarball with only a repository-final newline added. The Octane port:
|
|
13
|
+
|
|
14
|
+
- converts `src/ReactCrop.tsx` from a React `PureComponent` to the hook-backed `src/ReactCrop.tsrx` function component;
|
|
15
|
+
- reuses the framework-neutral `types.ts`, `utils.ts`, and `addons/browserCrop.ts` source unchanged;
|
|
16
|
+
- publishes `src/ReactCrop.css`, copied from the pinned npm distribution's compiled Sass output with only Vite's trailing build sentinel omitted;
|
|
17
|
+
- keeps native pointer and keyboard events and preserves the public callback name `onChange`.
|
|
18
|
+
|
|
19
|
+
The vendored `upstream/` tree is development evidence and is not included in the published package.
|
|
20
|
+
|
|
21
|
+
## Export crosswalk
|
|
22
|
+
|
|
23
|
+
| Upstream export | Octane disposition | Evidence |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `ReactCrop` | Ported to an Octane function component; class instance storage is represented by refs and local state by hooks. | `tests/image-crop.test.ts` |
|
|
26
|
+
| `default` | Alias of `ReactCrop`, matching upstream. | `tests/image-crop.test.ts` |
|
|
27
|
+
| `Component` | Legacy alias of `ReactCrop`, matching upstream. | `tests/image-crop.test.ts` |
|
|
28
|
+
| `ReactCropProps`, `ReactCropState` | Ported to native DOM event types and `OctaneNode`; the public property names and crop callback shapes are preserved. | `src/ReactCrop.tsrx` |
|
|
29
|
+
| `Crop`, `PixelCrop`, `PercentCrop`, `Ords`, `XOrds`, `YOrds`, `XYOrds` | Reused framework-neutral public types. | `src/types.ts` |
|
|
30
|
+
| `defaultCrop`, `clamp`, `cls`, `areCropsEqual` | Reused framework-neutral utilities. | `src/utils.ts` |
|
|
31
|
+
| `makeAspectCrop`, `centerCrop` | Reused framework-neutral crop construction utilities. | `tests/image-crop.test.ts` |
|
|
32
|
+
| `convertToPercentCrop`, `convertToPixelCrop`, `containCrop`, `nudgeCrop` | Reused framework-neutral crop conversion and constraint utilities. | `src/utils.ts`, `tests/image-crop.test.ts` |
|
|
33
|
+
| `cropToCanvas`, `cropToImg` | Reused framework-neutral browser crop helpers. | `src/addons/browserCrop.ts` |
|
|
34
|
+
| `./dist/ReactCrop.css` | Mapped to the compiled CSS in `src/ReactCrop.css`. | `tests/image-crop.test.ts` |
|
|
35
|
+
| `./src/ReactCrop.scss` | Compatibility export mapped to compiled CSS because published packages ship authored consumable source, not a Sass build requirement. | `tests/image-crop.test.ts` |
|
|
36
|
+
|
|
37
|
+
## Upstream tests
|
|
38
|
+
|
|
39
|
+
The canonical repository at the pinned commit has no unit-test files, test configuration, or `test` package script. Its scripts are `dev`, `build`, `lint`, `preview`, and `prepare`, and its `src/demo/` application is a manual demonstration rather than a test suite. This conclusion comes from the pinned repository metadata and tree, not from the npm tarball's contents.
|
|
40
|
+
|
|
41
|
+
The Octane package therefore supplies focused package-authored behavior tests for rendering, crop styling, native pointer updates, crop utilities, aliases, and stylesheet exports. These tests are Octane framework-contract evidence; they are not presented as an adapted upstream suite.
|
|
42
|
+
|
|
43
|
+
## Intentional framework adaptation
|
|
44
|
+
|
|
45
|
+
Octane has no class components or synthetic event objects. `ReactCrop` is a named function component using Octane hooks, and its handlers receive native `PointerEvent` and `KeyboardEvent` objects. The public API and crop math are otherwise preserved at the pinned release.
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@octanejs/image-crop",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "react-image-crop for Octane with matching crop interaction behavior.",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.22.2"
|
|
9
|
+
},
|
|
10
|
+
"author": {
|
|
11
|
+
"name": "Dominic Gannaway",
|
|
12
|
+
"email": "dg@domgan.com"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/octanejs/octane.git",
|
|
20
|
+
"directory": "packages/image-crop"
|
|
21
|
+
},
|
|
22
|
+
"main": "./src/index.ts",
|
|
23
|
+
"module": "./src/index.ts",
|
|
24
|
+
"types": "./src/index.ts",
|
|
25
|
+
"style": "./src/ReactCrop.css",
|
|
26
|
+
"files": [
|
|
27
|
+
"src",
|
|
28
|
+
"README.md",
|
|
29
|
+
"UPSTREAM.md",
|
|
30
|
+
"LICENSE"
|
|
31
|
+
],
|
|
32
|
+
"sideEffects": [
|
|
33
|
+
"./src/ReactCrop.css"
|
|
34
|
+
],
|
|
35
|
+
"exports": {
|
|
36
|
+
".": "./src/index.ts",
|
|
37
|
+
"./dist/ReactCrop.css": "./src/ReactCrop.css",
|
|
38
|
+
"./ReactCrop.css": "./src/ReactCrop.css",
|
|
39
|
+
"./src/ReactCrop.scss": "./src/ReactCrop.css",
|
|
40
|
+
"./package.json": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"octane": "0.1.45"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"typescript": "^5.9.3",
|
|
47
|
+
"vitest": "^4.1.10",
|
|
48
|
+
"octane": "0.1.45"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"test": "vitest run --root ../.. --project image-crop",
|
|
52
|
+
"typecheck": "tsrx-tsc --noEmit -p tsconfig.json && tsrx-tsc --noEmit -p tsconfig.tests.json"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@keyframes marching-ants{0%{background-position:0 0,0 100%,0 0,100% 0}to{background-position:20px 0,-20px 100%,0 -20px,100% 20px}}:root{--rc-drag-handle-size:12px;--rc-drag-handle-mobile-size:24px;--rc-drag-handle-bg-colour:#0003;--rc-drag-bar-size:6px;--rc-border-color:#ffffffb3;--rc-focus-color:#08f}.ReactCrop{cursor:crosshair;max-width:100%;display:inline-block;position:relative}.ReactCrop *,.ReactCrop :before,.ReactCrop :after{box-sizing:border-box}.ReactCrop--disabled,.ReactCrop--locked{cursor:inherit}.ReactCrop__child-wrapper{max-height:inherit;overflow:hidden}.ReactCrop__child-wrapper>img,.ReactCrop__child-wrapper>video{max-width:100%;max-height:inherit;display:block}.ReactCrop:not(.ReactCrop--disabled) .ReactCrop__child-wrapper>img,.ReactCrop:not(.ReactCrop--disabled) .ReactCrop__child-wrapper>video,.ReactCrop:not(.ReactCrop--disabled) .ReactCrop__crop-selection{touch-action:none}.ReactCrop__crop-mask{pointer-events:none;width:calc(100% + .5px);height:calc(100% + .5px);position:absolute;inset:0}.ReactCrop__crop-selection{cursor:move;position:absolute;top:0;left:0;transform:translate(0,0)}.ReactCrop--disabled .ReactCrop__crop-selection{cursor:inherit}.ReactCrop--circular-crop .ReactCrop__crop-selection{border-radius:50%}.ReactCrop--circular-crop .ReactCrop__crop-selection:after{pointer-events:none;content:"";border:1px solid var(--rc-border-color);opacity:.3;position:absolute;inset:-1px}.ReactCrop--no-animate .ReactCrop__crop-selection{outline:1px dashed #fff}.ReactCrop__crop-selection:not(.ReactCrop--no-animate .ReactCrop__crop-selection){color:#fff;background-image:linear-gradient(90deg,#fff 50%,#444 50%),linear-gradient(90deg,#fff 50%,#444 50%),linear-gradient(#fff 50%,#444 50%),linear-gradient(#fff 50%,#444 50%);background-position:0 0,0 100%,0 0,100% 0;background-repeat:repeat-x,repeat-x,repeat-y,repeat-y;background-size:10px 1px,10px 1px,1px 10px,1px 10px;animation:1s linear infinite marching-ants}.ReactCrop__crop-selection:focus{outline:2px solid var(--rc-focus-color);outline-offset:-1px}.ReactCrop--invisible-crop .ReactCrop__crop-mask,.ReactCrop--invisible-crop .ReactCrop__crop-selection{display:none}.ReactCrop__rule-of-thirds-vt:before,.ReactCrop__rule-of-thirds-vt:after,.ReactCrop__rule-of-thirds-hz:before,.ReactCrop__rule-of-thirds-hz:after{content:"";background-color:#fff6;display:block;position:absolute}.ReactCrop__rule-of-thirds-vt:before,.ReactCrop__rule-of-thirds-vt:after{width:1px;height:100%}.ReactCrop__rule-of-thirds-vt:before{left:33.3333%}.ReactCrop__rule-of-thirds-vt:after{left:66.6667%}.ReactCrop__rule-of-thirds-hz:before,.ReactCrop__rule-of-thirds-hz:after{width:100%;height:1px}.ReactCrop__rule-of-thirds-hz:before{top:33.3333%}.ReactCrop__rule-of-thirds-hz:after{top:66.6667%}.ReactCrop__drag-handle{width:var(--rc-drag-handle-size);height:var(--rc-drag-handle-size);background-color:var(--rc-drag-handle-bg-colour);border:1px solid var(--rc-border-color);position:absolute}.ReactCrop__drag-handle:focus{background:var(--rc-focus-color)}.ReactCrop .ord-nw{cursor:nw-resize;top:0;left:0;transform:translate(-50%,-50%)}.ReactCrop .ord-n{cursor:n-resize;top:0;left:50%;transform:translate(-50%,-50%)}.ReactCrop .ord-ne{cursor:ne-resize;top:0;right:0;transform:translate(50%,-50%)}.ReactCrop .ord-e{cursor:e-resize;top:50%;right:0;transform:translate(50%,-50%)}.ReactCrop .ord-se{cursor:se-resize;bottom:0;right:0;transform:translate(50%,50%)}.ReactCrop .ord-s{cursor:s-resize;bottom:0;left:50%;transform:translate(-50%,50%)}.ReactCrop .ord-sw{cursor:sw-resize;bottom:0;left:0;transform:translate(-50%,50%)}.ReactCrop .ord-w{cursor:w-resize;top:50%;left:0;transform:translate(-50%,-50%)}.ReactCrop__disabled .ReactCrop__drag-handle{cursor:inherit}.ReactCrop__drag-bar{position:absolute}.ReactCrop__drag-bar.ord-n{width:100%;height:var(--rc-drag-bar-size);top:0;left:0;transform:translateY(-50%)}.ReactCrop__drag-bar.ord-e{width:var(--rc-drag-bar-size);height:100%;top:0;right:0;transform:translate(50%)}.ReactCrop__drag-bar.ord-s{width:100%;height:var(--rc-drag-bar-size);bottom:0;left:0;transform:translateY(50%)}.ReactCrop__drag-bar.ord-w{width:var(--rc-drag-bar-size);height:100%;top:0;left:0;transform:translate(-50%)}.ReactCrop--new-crop .ReactCrop__drag-bar,.ReactCrop--new-crop .ReactCrop__drag-handle,.ReactCrop--fixed-aspect .ReactCrop__drag-bar,.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-n,.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-e,.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-s,.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-w{display:none}@media (pointer:coarse){.ReactCrop .ord-n,.ReactCrop .ord-e,.ReactCrop .ord-s,.ReactCrop .ord-w{display:none}.ReactCrop__drag-handle{width:var(--rc-drag-handle-mobile-size);height:var(--rc-drag-handle-mobile-size)}}
|