create-cloudinary-react 1.0.0-beta.16 → 1.0.0-beta.18

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/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ # [1.0.0-beta.18](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.17...v1.0.0-beta.18) (2026-02-18)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * update registration link ([2a69d7a](https://github.com/cloudinary-devs/create-cloudinary-react/commit/2a69d7ada9de1cb2751bbd4c1d344422b4c2dd5e))
7
+ * update video player example ([9db39ee](https://github.com/cloudinary-devs/create-cloudinary-react/commit/9db39ee8fc149c748ea422544a79b45a60365f47))
8
+
9
+ # [1.0.0-beta.17](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.16...v1.0.0-beta.17) (2026-02-12)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * simplified questions into arrays ([bade600](https://github.com/cloudinary-devs/create-cloudinary-react/commit/bade600ee63de7a7c3d8eec40569f8896f96a7bd))
15
+
16
+
17
+ ### Features
18
+
19
+ * prompt copied animation ([9ad35b2](https://github.com/cloudinary-devs/create-cloudinary-react/commit/9ad35b2351a69bca6d4dcd716b10a1508d5228a8))
20
+
1
21
  # [1.0.0-beta.16](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.15...v1.0.0-beta.16) (2026-02-11)
2
22
 
3
23
 
package/README.md CHANGED
@@ -10,7 +10,7 @@ Scaffold a Cloudinary React + Vite + TypeScript project with interactive setup.
10
10
 
11
11
  - Node.js 18+ installed
12
12
  - A Cloudinary account (free tier available)
13
- - [Sign up for free](https://cloudinary.com/users/register/free)
13
+ - [Sign up for free](https://cld.media/reactregister)
14
14
  - Your cloud name is in your [dashboard](https://console.cloudinary.com/app/home/dashboard)
15
15
 
16
16
  ## Usage
package/cli.js CHANGED
@@ -70,7 +70,7 @@ async function main() {
70
70
  } else {
71
71
 
72
72
  console.log(chalk.cyan.bold('\nšŸš€ Cloudinary React + Vite\n'));
73
- console.log(chalk.gray('šŸ’” Need a Cloudinary account? Sign up for free: https://cloudinary.com/users/register/free\n'));
73
+ console.log(chalk.gray('šŸ’” Need a Cloudinary account? Sign up for free: https://cld.media/reactregister\n'));
74
74
 
75
75
  const questions = [
76
76
  {
@@ -101,7 +101,7 @@ async function main() {
101
101
  if (!input.trim()) {
102
102
  return chalk.yellow(
103
103
  'Cloud name is required.\n' +
104
- ' → Sign up: https://cloudinary.com/users/register/free\n' +
104
+ ' → Sign up: https://cld.media/reactregister\n' +
105
105
  ' → Find your cloud name: https://console.cloudinary.com/app/home/dashboard'
106
106
  );
107
107
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-cloudinary-react",
3
- "version": "1.0.0-beta.16",
3
+ "version": "1.0.0-beta.18",
4
4
  "description": "Scaffold a Cloudinary React + Vite + TypeScript project with interactive setup",
5
5
  "type": "module",
6
6
  "bin": {
@@ -420,7 +420,8 @@ Use when the user asks for a **video player** (styled UI, controls, playlists).
420
420
  **Rule: imperative element only.** Do **not** pass a React-managed `<video ref={...} />` to the player — the library mutates the DOM and React will throw removeChild errors. Create the video element with `document.createElement('video')`, append it to a container ref, and pass that element to `videoPlayer(el, ...)`.
421
421
 
422
422
  - **Package**: `cloudinary-video-player`. Install with `npm install cloudinary-video-player` (no version).
423
- - **Import**: `import { videoPlayer } from 'cloudinary-video-player'` (named) and `import 'cloudinary-video-player/cld-video-player.min.css'` (no `dist/` in path).
423
+ - **Import**: `import { videoPlayer } from 'cloudinary-video-player'` (named) and `import 'cloudinary-video-player/cld-video-player.min.css'` (no `dist/` in path). The package only exposes paths under `lib/` via `exports`; use `cld-video-player.min.css` (no `dist/`), which resolves to `lib/cld-video-player.min.css`.
424
+ - āŒ **WRONG**: `import 'cloudinary-video-player/dist/cld-video-player.min.css'` — package `exports` do not expose `dist/`; the valid path is `cloudinary-video-player/cld-video-player.min.css`.
424
425
  - **player.source()** takes an **object**: `player.source({ publicId: 'samples/elephants' })`. Not a string.
425
426
  - **Cleanup**: Call `player.dispose()`, then **only if** `el.parentNode` exists call `el.parentNode.removeChild(el)` (avoids NotFoundError).
426
427
  - **If init fails** (CSP, extensions, timing): render **AdvancedVideo** with the same publicId. Do not relax CSP in index.html or ask the user to disable extensions.
@@ -11,7 +11,7 @@ npm run dev
11
11
  ## Cloudinary Setup
12
12
 
13
13
  This project uses Cloudinary for image management. If you don't have a Cloudinary account yet:
14
- - [Sign up for free](https://cloudinary.com/users/register/free)
14
+ - [Sign up for free](https://cld.media/reactregister)
15
15
  - Find your cloud name in your [dashboard](https://console.cloudinary.com/app/home/dashboard)
16
16
 
17
17
  ## Environment Variables
@@ -91,6 +91,7 @@ h2 {
91
91
  transition: all 0.2s;
92
92
  user-select: text;
93
93
  cursor: pointer;
94
+ position: relative;
94
95
  }
95
96
 
96
97
  .prompts-list li:hover {
@@ -98,3 +99,67 @@ h2 {
98
99
  border-left-color: rgba(99, 102, 241, 0.8);
99
100
  transform: translateX(4px);
100
101
  }
102
+
103
+ @keyframes wipe-in-out {
104
+ 0% {
105
+ clip-path: polygon(
106
+ 0% 0%,
107
+ 0% 100%,
108
+ 0% 100%,
109
+ 0% 0%
110
+ );
111
+ }
112
+ 15% {
113
+ clip-path: polygon(
114
+ 0% 0%,
115
+ 0% 100%,
116
+ 100% 100%,
117
+ 100% 0%
118
+ );
119
+ }
120
+ 85% {
121
+ clip-path: polygon(
122
+ 0% 0%,
123
+ 0% 100%,
124
+ 100% 100%,
125
+ 100% 0%
126
+ );
127
+ }
128
+ 100% {
129
+ clip-path: polygon(
130
+ 100% 0%,
131
+ 100% 100%,
132
+ 100% 100%,
133
+ 100% 0%
134
+ );
135
+ }
136
+ }
137
+
138
+ .prompts-list li::after {
139
+ content: 'āœ“ copied';
140
+ position: absolute;
141
+ left: 0;
142
+ right: 0;
143
+ top: 0;
144
+ bottom: 0;
145
+ background-color: green;
146
+ border-radius: 0.5rem;
147
+ visibility: hidden;
148
+ padding-top: 0.75em;
149
+ padding-left: 1em;
150
+
151
+ /* without this it sometimes glitched at the end? */
152
+ clip-path: polygon(
153
+ 0% 0%,
154
+ 0% 100%,
155
+ 0% 100%,
156
+ 0% 0%
157
+ );
158
+
159
+ }
160
+
161
+ .prompts-list li.clicked::after {
162
+ visibility: visible;
163
+ animation-duration: 1.5s;
164
+ animation-name: wipe-in-out;
165
+ }
@@ -12,8 +12,20 @@ import './App.css';
12
12
 
13
13
  const hasUploadPreset = Boolean(uploadPreset);
14
14
 
15
+ const PROMPTS_WITH_UPLOAD = [
16
+ 'Create an image gallery with lazy loading and responsive images',
17
+ 'Create a video player that plays a Cloudinary video',
18
+ 'Add image overlays with text or logos',
19
+ ];
20
+
21
+ const PROMPTS_WITHOUT_UPLOAD = [
22
+ "Let's try uploading — help me add an upload preset and upload widget",
23
+ ...PROMPTS_WITH_UPLOAD,
24
+ ];
25
+
15
26
  function App() {
16
27
  const [uploadedImageId, setUploadedImageId] = useState<string | null>(null);
28
+ const [clickedIds, setClickedIds] = useState(new Set<number>());
17
29
 
18
30
  const handleUploadSuccess = (result: CloudinaryUploadResult) => {
19
31
  console.log('Upload successful:', result);
@@ -25,9 +37,15 @@ function App() {
25
37
  alert(`Upload failed: ${error.message}`);
26
38
  };
27
39
 
28
- const copyPrompt = (e: React.MouseEvent<HTMLLIElement>) => {
29
- const text = e.currentTarget.textContent ?? '';
30
- void navigator.clipboard.writeText(text);
40
+ const copyPrompt = (text: string, id: number) => {
41
+ void navigator.clipboard.writeText(text).then(() => {
42
+ setClickedIds((prev) => new Set(prev).add(id));
43
+ setTimeout(() => setClickedIds( (prev) => {
44
+ const next = new Set(prev);
45
+ next.delete(id);
46
+ return next;
47
+ }), 2000);
48
+ });
31
49
  };
32
50
 
33
51
  // Display uploaded image if available, otherwise show a sample
@@ -75,20 +93,16 @@ function App() {
75
93
  <strong>Copy and paste</strong> one of these prompts into your AI assistant:
76
94
  </p>
77
95
  <ul className="prompts-list">
78
- {hasUploadPreset ? (
79
- <>
80
- <li onClick={copyPrompt} title="Click to copy">Create an image gallery with lazy loading and responsive images</li>
81
- <li onClick={copyPrompt} title="Click to copy">Create a video player that plays a Cloudinary video</li>
82
- <li onClick={copyPrompt} title="Click to copy">Add image overlays with text or logos</li>
83
- </>
84
- ) : (
85
- <>
86
- <li onClick={copyPrompt} title="Click to copy">Let&apos;s try uploading — help me add an upload preset and upload widget</li>
87
- <li onClick={copyPrompt} title="Click to copy">Create an image gallery with lazy loading and responsive images</li>
88
- <li onClick={copyPrompt} title="Click to copy">Create a video player that plays a Cloudinary video</li>
89
- <li onClick={copyPrompt} title="Click to copy">Add image overlays with text or logos</li>
90
- </>
91
- )}
96
+ {(hasUploadPreset ? PROMPTS_WITH_UPLOAD : PROMPTS_WITHOUT_UPLOAD).map((text, i) => (
97
+ <li
98
+ key={i}
99
+ onClick={() => copyPrompt(text, i)}
100
+ title="Click to copy"
101
+ className={clickedIds.has(i) ? 'clicked' : ''}
102
+ >
103
+ {text}
104
+ </li>
105
+ ))}
92
106
  </ul>
93
107
  </div>
94
108
  </main>