chore: sync React samples from npm

This commit is contained in:
svc-idee-bot 2026-04-23 17:19:58 +00:00
parent 1b1cd519c4
commit 5fec34fe7a
23 changed files with 1787 additions and 1396 deletions

44
package-lock.json generated
View File

@ -1,16 +1,16 @@
{ {
"name": "@salesforce/afv-skills", "name": "@salesforce/afv-skills",
"version": "1.6.8", "version": "1.7.3",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@salesforce/afv-skills", "name": "@salesforce/afv-skills",
"version": "1.6.8", "version": "1.7.3",
"license": "CC-BY-NC-4.0", "license": "CC-BY-NC-4.0",
"devDependencies": { "devDependencies": {
"@salesforce/ui-bundle-template-app-react-sample-b2e": "^1.120.6", "@salesforce/ui-bundle-template-app-react-sample-b2e": "^1.128.0",
"@salesforce/ui-bundle-template-app-react-sample-b2x": "^1.120.6", "@salesforce/ui-bundle-template-app-react-sample-b2x": "^1.128.0",
"@salesforce/webapp-template-app-react-sample-b2e-experimental": "^1.117.1", "@salesforce/webapp-template-app-react-sample-b2e-experimental": "^1.117.1",
"@salesforce/webapp-template-app-react-sample-b2x-experimental": "^1.117.1", "@salesforce/webapp-template-app-react-sample-b2x-experimental": "^1.117.1",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
@ -690,22 +690,22 @@
} }
}, },
"node_modules/@salesforce/sdk-core": { "node_modules/@salesforce/sdk-core": {
"version": "1.120.6", "version": "1.128.0",
"resolved": "https://registry.npmjs.org/@salesforce/sdk-core/-/sdk-core-1.120.6.tgz", "resolved": "https://registry.npmjs.org/@salesforce/sdk-core/-/sdk-core-1.128.0.tgz",
"integrity": "sha512-yqd3Cf5hPzMJTy9GEsy9N41oFFIrcAOU/QuDDZ+nAmmXNmprM3kt93JCdhHr2L1P6JP2SHMhNMJQ1lKmSPl/uw==", "integrity": "sha512-akWlQRfEQH+GH8BWZjt+JWB8XOo3xYiXVvWjSQEbgIFCUUfu9oPrvf6Tqxxtf6ayznSHGPZC2ZTJGwRFGsgR8w==",
"dev": true, "dev": true,
"license": "SEE LICENSE IN LICENSE.txt" "license": "SEE LICENSE IN LICENSE.txt"
}, },
"node_modules/@salesforce/sdk-data": { "node_modules/@salesforce/sdk-data": {
"version": "1.120.6", "version": "1.128.0",
"resolved": "https://registry.npmjs.org/@salesforce/sdk-data/-/sdk-data-1.120.6.tgz", "resolved": "https://registry.npmjs.org/@salesforce/sdk-data/-/sdk-data-1.128.0.tgz",
"integrity": "sha512-ejVCIU3EJTt2uv1kKx/3Jg98ESHbuG5zh+sn1Z4rfxtU/jVzeLZQyS3dIjw1krhSFIl9He+JU5EW8/s5W6aQSA==", "integrity": "sha512-rXeXIjSXLDnv3n7yHhXs/Hv+N/i2qOQqLqeiWcgBWhg+uRqFGdSy7H7WlyQ0pxNwk4XY0/BAouRFlIdxsnSIbQ==",
"dev": true, "dev": true,
"license": "SEE LICENSE IN LICENSE.txt", "license": "SEE LICENSE IN LICENSE.txt",
"dependencies": { "dependencies": {
"@conduit-client/service-fetch-network": "3.17.0", "@conduit-client/service-fetch-network": "3.17.0",
"@conduit-client/utils": "3.17.0", "@conduit-client/utils": "3.17.0",
"@salesforce/sdk-core": "^1.120.6" "@salesforce/sdk-core": "^1.128.0"
} }
}, },
"node_modules/@salesforce/ts-types": { "node_modules/@salesforce/ts-types": {
@ -719,14 +719,14 @@
} }
}, },
"node_modules/@salesforce/ui-bundle": { "node_modules/@salesforce/ui-bundle": {
"version": "1.120.6", "version": "1.128.0",
"resolved": "https://registry.npmjs.org/@salesforce/ui-bundle/-/ui-bundle-1.120.6.tgz", "resolved": "https://registry.npmjs.org/@salesforce/ui-bundle/-/ui-bundle-1.128.0.tgz",
"integrity": "sha512-sIHzbSMkMwvhh7IzAO/TzTMjIdphf8dTu+A4+LHobQ0XLp9Y0dii1ckMhLTb/i97qdCDq+aeIIKVQpRedgjsTw==", "integrity": "sha512-dd2HHsvvKFpBiRvVRkWNWzW7axGyT1j5fq5Yk3ZzLDs9t4OhBHy5Ulj7WCRTLbD2Pydlrhqmli4q44mAkExGxA==",
"dev": true, "dev": true,
"license": "SEE LICENSE IN LICENSE.txt", "license": "SEE LICENSE IN LICENSE.txt",
"dependencies": { "dependencies": {
"@salesforce/core": "^8.23.4", "@salesforce/core": "^8.23.4",
"@salesforce/sdk-data": "^1.120.6", "@salesforce/sdk-data": "^1.128.0",
"micromatch": "^4.0.8", "micromatch": "^4.0.8",
"path-to-regexp": "^8.3.0" "path-to-regexp": "^8.3.0"
}, },
@ -735,20 +735,20 @@
} }
}, },
"node_modules/@salesforce/ui-bundle-template-app-react-sample-b2e": { "node_modules/@salesforce/ui-bundle-template-app-react-sample-b2e": {
"version": "1.120.6", "version": "1.128.0",
"resolved": "https://registry.npmjs.org/@salesforce/ui-bundle-template-app-react-sample-b2e/-/ui-bundle-template-app-react-sample-b2e-1.120.6.tgz", "resolved": "https://registry.npmjs.org/@salesforce/ui-bundle-template-app-react-sample-b2e/-/ui-bundle-template-app-react-sample-b2e-1.128.0.tgz",
"integrity": "sha512-/A31Oon0gRvs+kshC55T2VoaEqDNfnwsSfJNfCi8Y4Y2UeGuMNtd4tvRrahQ6+QBup4NWUdOQNIwJWaXUWDC4A==", "integrity": "sha512-eqFltrf6oTPWu3t6i7t/IA41XXWFf86+7TrApk/9gNg3GYCH/D5qPXhaCBkwdNYkK8+5q38MYqknnYYP6VKeBg==",
"dev": true, "dev": true,
"license": "SEE LICENSE IN LICENSE.txt", "license": "SEE LICENSE IN LICENSE.txt",
"dependencies": { "dependencies": {
"@salesforce/ui-bundle": "^1.120.6", "@salesforce/ui-bundle": "^1.128.0",
"sonner": "^1.7.0" "sonner": "^1.7.0"
} }
}, },
"node_modules/@salesforce/ui-bundle-template-app-react-sample-b2x": { "node_modules/@salesforce/ui-bundle-template-app-react-sample-b2x": {
"version": "1.120.6", "version": "1.128.0",
"resolved": "https://registry.npmjs.org/@salesforce/ui-bundle-template-app-react-sample-b2x/-/ui-bundle-template-app-react-sample-b2x-1.120.6.tgz", "resolved": "https://registry.npmjs.org/@salesforce/ui-bundle-template-app-react-sample-b2x/-/ui-bundle-template-app-react-sample-b2x-1.128.0.tgz",
"integrity": "sha512-j0joo4RYXM9OnVpZX4vb8nI/AMw9Uxz6xzm9o8KQ8WkU79P20xBdRTKBS1H379rpWV0KcxaMFBx6qGV82jgLNA==", "integrity": "sha512-+TQFzKyylbhr86F0lnsErzXFLkq3o8L1mXLJT4ZzDtXw2RlbYfkolUrkTxVl8fGal/QPPYcT4owdgaMNMTLhdQ==",
"dev": true, "dev": true,
"license": "SEE LICENSE IN LICENSE.txt" "license": "SEE LICENSE IN LICENSE.txt"
}, },

View File

@ -11,8 +11,8 @@
"registry": "https://registry.npmjs.org" "registry": "https://registry.npmjs.org"
}, },
"devDependencies": { "devDependencies": {
"@salesforce/ui-bundle-template-app-react-sample-b2e": "^1.120.6", "@salesforce/ui-bundle-template-app-react-sample-b2e": "^1.128.0",
"@salesforce/ui-bundle-template-app-react-sample-b2x": "^1.120.6", "@salesforce/ui-bundle-template-app-react-sample-b2x": "^1.128.0",
"@salesforce/webapp-template-app-react-sample-b2e-experimental": "^1.117.1", "@salesforce/webapp-template-app-react-sample-b2e-experimental": "^1.117.1",
"@salesforce/webapp-template-app-react-sample-b2x-experimental": "^1.117.1", "@salesforce/webapp-template-app-react-sample-b2x-experimental": "^1.117.1",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",

View File

@ -1 +1 @@
1.120.6 1.128.0

View File

@ -3,6 +3,105 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.128.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.127.0...v1.128.0) (2026-04-23)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.127.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.126.0...v1.127.0) (2026-04-22)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.126.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.125.1...v1.126.0) (2026-04-22)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
## [1.125.1](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.125.0...v1.125.1) (2026-04-16)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.125.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.124.0...v1.125.0) (2026-04-15)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.124.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.123.0...v1.124.0) (2026-04-15)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.123.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.122.2...v1.123.0) (2026-04-13)
### Bug Fixes
* **template:** stop auto-starting dev server after sf-project-setup ([#429](https://github.com/salesforce-experience-platform-emu/webapps/issues/429)) ([5e7e7cf](https://github.com/salesforce-experience-platform-emu/webapps/commit/5e7e7cfb9dc1c5c000b1e825307dde9eb847697b))
## [1.122.2](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.122.1...v1.122.2) (2026-04-13)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
## [1.122.1](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.122.0...v1.122.1) (2026-04-10)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.122.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.121.0...v1.122.0) (2026-04-09)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.121.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.7...v1.121.0) (2026-04-09)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
## [1.120.7](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.6...v1.120.7) (2026-04-08)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
## [1.120.6](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.5...v1.120.6) (2026-04-07) ## [1.120.6](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.5...v1.120.6) (2026-04-07)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project **Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project

View File

@ -18,8 +18,8 @@
"graphql:schema": "node scripts/get-graphql-schema.mjs" "graphql:schema": "node scripts/get-graphql-schema.mjs"
}, },
"dependencies": { "dependencies": {
"@salesforce/sdk-data": "^1.120.6", "@salesforce/sdk-data": "^1.128.0",
"@salesforce/ui-bundle": "^1.120.6", "@salesforce/ui-bundle": "^1.128.0",
"@tailwindcss/vite": "^4.1.17", "@tailwindcss/vite": "^4.1.17",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
@ -46,7 +46,7 @@
"@graphql-eslint/eslint-plugin": "^4.1.0", "@graphql-eslint/eslint-plugin": "^4.1.0",
"@graphql-tools/utils": "^11.0.0", "@graphql-tools/utils": "^11.0.0",
"@playwright/test": "^1.49.0", "@playwright/test": "^1.49.0",
"@salesforce/vite-plugin-ui-bundle": "^1.120.6", "@salesforce/vite-plugin-ui-bundle": "^1.128.0",
"@testing-library/jest-dom": "^6.6.3", "@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.1.0", "@testing-library/react": "^16.1.0",
"@testing-library/user-event": "^14.5.2", "@testing-library/user-event": "^14.5.2",

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from "react"; import { useEffect, useRef, useState } from "react";
interface UseAsyncDataResult<T> { interface UseAsyncDataResult<T> {
data: T | null; data: T | null;
@ -23,17 +23,18 @@ export function useAsyncData<T>(
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
// Re-create the fetcher reference only when deps change. const fetcherRef = useRef(fetcher);
// eslint-disable-next-line react-hooks/exhaustive-deps --- deps are explicitly managed by the caller useEffect(() => {
const memoizedFetcher = useCallback(fetcher, deps); fetcherRef.current = fetcher;
});
useEffect(() => { useEffect(() => {
// Guard against setting state after unmount or dep change.
let cancelled = false; let cancelled = false;
setLoading(true); setLoading(true);
setError(null); setError(null);
memoizedFetcher() fetcherRef
.current()
.then((result) => { .then((result) => {
if (!cancelled) setData(result); if (!cancelled) setData(result);
}) })
@ -48,7 +49,8 @@ export function useAsyncData<T>(
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [memoizedFetcher]); // eslint-disable-next-line react-hooks/exhaustive-deps --- deps are explicitly managed by the caller
}, deps);
return { data, loading, error }; return { data, loading, error };
} }

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from "react"; import { useEffect, useRef, useState } from "react";
interface UseAsyncDataResult<T> { interface UseAsyncDataResult<T> {
data: T | null; data: T | null;
@ -139,8 +139,10 @@ export function useCachedAsyncData<T>(
const [loading, setLoading] = useState(!cached); const [loading, setLoading] = useState(!cached);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
// eslint-disable-next-line react-hooks/exhaustive-deps --- deps are explicitly managed by the caller const fetcherRef = useRef(fetcher);
const memoizedFetcher = useCallback(fetcher, deps); useEffect(() => {
fetcherRef.current = fetcher;
});
useEffect(() => { useEffect(() => {
// Re-check the cache inside the effect because deps may have changed // Re-check the cache inside the effect because deps may have changed
@ -158,7 +160,8 @@ export function useCachedAsyncData<T>(
setLoading(true); setLoading(true);
setError(null); setError(null);
memoizedFetcher() fetcherRef
.current()
.then((result) => { .then((result) => {
if (!cancelled) { if (!cancelled) {
setEntry(cacheKey, result, maxSize); setEntry(cacheKey, result, maxSize);
@ -178,7 +181,8 @@ export function useCachedAsyncData<T>(
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [memoizedFetcher, cacheKey, ttl, maxSize]); // eslint-disable-next-line react-hooks/exhaustive-deps --- deps are explicitly managed by the caller
}, [...deps, cacheKey, ttl, maxSize]);
return { data, loading, error }; return { data, loading, error };
} }

View File

@ -113,7 +113,9 @@ export function useObjectSearchParams<TFilter, TOrderBy>(
// Snapshot ref — lets callbacks read the latest state without being // Snapshot ref — lets callbacks read the latest state without being
// recreated on every render (avoids infinite useCallback chains). // recreated on every render (avoids infinite useCallback chains).
const stateRef = useRef({ filters, sort, pageSize, pageIndex }); const stateRef = useRef({ filters, sort, pageSize, pageIndex });
stateRef.current = { filters, sort, pageSize, pageIndex }; useEffect(() => {
stateRef.current = { filters, sort, pageSize, pageIndex };
});
// Any filter/sort change resets pagination to the first page. // Any filter/sort change resets pagination to the first page.
const resetPagination = useCallback(() => { const resetPagination = useCallback(() => {

View File

@ -1,12 +1,12 @@
{ {
"name": "@salesforce/webapp-template-base-sfdx-project-experimental", "name": "@salesforce/webapp-template-base-sfdx-project-experimental",
"version": "1.120.6", "version": "1.128.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@salesforce/webapp-template-base-sfdx-project-experimental", "name": "@salesforce/webapp-template-base-sfdx-project-experimental",
"version": "1.120.6", "version": "1.128.0",
"license": "SEE LICENSE IN LICENSE.txt", "license": "SEE LICENSE IN LICENSE.txt",
"devDependencies": { "devDependencies": {
"@lwc/eslint-plugin-lwc": "^3.3.0", "@lwc/eslint-plugin-lwc": "^3.3.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "@salesforce/ui-bundle-template-base-sfdx-project", "name": "@salesforce/ui-bundle-template-base-sfdx-project",
"version": "1.120.6", "version": "1.128.0",
"description": "Base SFDX project template", "description": "Base SFDX project template",
"license": "SEE LICENSE IN LICENSE.txt", "license": "SEE LICENSE IN LICENSE.txt",
"publishConfig": { "publishConfig": {

View File

@ -101,5 +101,3 @@ console.log('UI bundle directory:', uiBundleDir);
run('npm install', 'npm', ['install', '--registry', 'https://registry.npmjs.org/'], { cwd: uiBundleDir }); run('npm install', 'npm', ['install', '--registry', 'https://registry.npmjs.org/'], { cwd: uiBundleDir });
run('npm run build', 'npm', ['run', 'build'], { cwd: uiBundleDir }); run('npm run build', 'npm', ['run', 'build'], { cwd: uiBundleDir });
console.log('\n--- Launching dev server (Ctrl+C to stop) ---\n');
run('npm run dev', 'npm', ['run', 'dev'], { cwd: uiBundleDir });

View File

@ -1 +1 @@
1.120.6 1.128.0

View File

@ -3,6 +3,105 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.128.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.127.0...v1.128.0) (2026-04-23)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.127.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.126.0...v1.127.0) (2026-04-22)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.126.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.125.1...v1.126.0) (2026-04-22)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
## [1.125.1](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.125.0...v1.125.1) (2026-04-16)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.125.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.124.0...v1.125.0) (2026-04-15)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.124.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.123.0...v1.124.0) (2026-04-15)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.123.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.122.2...v1.123.0) (2026-04-13)
### Bug Fixes
* **template:** stop auto-starting dev server after sf-project-setup ([#429](https://github.com/salesforce-experience-platform-emu/webapps/issues/429)) ([5e7e7cf](https://github.com/salesforce-experience-platform-emu/webapps/commit/5e7e7cfb9dc1c5c000b1e825307dde9eb847697b))
## [1.122.2](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.122.1...v1.122.2) (2026-04-13)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
## [1.122.1](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.122.0...v1.122.1) (2026-04-10)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.122.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.121.0...v1.122.0) (2026-04-09)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
# [1.121.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.7...v1.121.0) (2026-04-09)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
## [1.120.7](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.6...v1.120.7) (2026-04-08)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
## [1.120.6](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.5...v1.120.6) (2026-04-07) ## [1.120.6](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.5...v1.120.6) (2026-04-07)
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project **Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project

View File

@ -18,8 +18,8 @@
"graphql:schema": "node scripts/get-graphql-schema.mjs" "graphql:schema": "node scripts/get-graphql-schema.mjs"
}, },
"dependencies": { "dependencies": {
"@salesforce/sdk-data": "^1.120.6", "@salesforce/sdk-data": "^1.128.0",
"@salesforce/ui-bundle": "^1.120.6", "@salesforce/ui-bundle": "^1.128.0",
"@tailwindcss/vite": "^4.1.17", "@tailwindcss/vite": "^4.1.17",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
@ -50,7 +50,7 @@
"@graphql-eslint/eslint-plugin": "^4.1.0", "@graphql-eslint/eslint-plugin": "^4.1.0",
"@graphql-tools/utils": "^11.0.0", "@graphql-tools/utils": "^11.0.0",
"@playwright/test": "^1.49.0", "@playwright/test": "^1.49.0",
"@salesforce/vite-plugin-ui-bundle": "^1.120.6", "@salesforce/vite-plugin-ui-bundle": "^1.128.0",
"@testing-library/jest-dom": "^6.6.3", "@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.1.0", "@testing-library/react": "^16.1.0",
"@testing-library/user-event": "^14.5.2", "@testing-library/user-event": "^14.5.2",

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from "react"; import { useEffect, useRef, useState } from "react";
interface UseAsyncDataResult<T> { interface UseAsyncDataResult<T> {
data: T | null; data: T | null;
@ -23,17 +23,18 @@ export function useAsyncData<T>(
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
// Re-create the fetcher reference only when deps change. const fetcherRef = useRef(fetcher);
// eslint-disable-next-line react-hooks/exhaustive-deps --- deps are explicitly managed by the caller useEffect(() => {
const memoizedFetcher = useCallback(fetcher, deps); fetcherRef.current = fetcher;
});
useEffect(() => { useEffect(() => {
// Guard against setting state after unmount or dep change.
let cancelled = false; let cancelled = false;
setLoading(true); setLoading(true);
setError(null); setError(null);
memoizedFetcher() fetcherRef
.current()
.then((result) => { .then((result) => {
if (!cancelled) setData(result); if (!cancelled) setData(result);
}) })
@ -48,7 +49,8 @@ export function useAsyncData<T>(
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [memoizedFetcher]); // eslint-disable-next-line react-hooks/exhaustive-deps --- deps are explicitly managed by the caller
}, deps);
return { data, loading, error }; return { data, loading, error };
} }

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from "react"; import { useEffect, useRef, useState } from "react";
interface UseAsyncDataResult<T> { interface UseAsyncDataResult<T> {
data: T | null; data: T | null;
@ -139,8 +139,10 @@ export function useCachedAsyncData<T>(
const [loading, setLoading] = useState(!cached); const [loading, setLoading] = useState(!cached);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
// eslint-disable-next-line react-hooks/exhaustive-deps --- deps are explicitly managed by the caller const fetcherRef = useRef(fetcher);
const memoizedFetcher = useCallback(fetcher, deps); useEffect(() => {
fetcherRef.current = fetcher;
});
useEffect(() => { useEffect(() => {
// Re-check the cache inside the effect because deps may have changed // Re-check the cache inside the effect because deps may have changed
@ -158,7 +160,8 @@ export function useCachedAsyncData<T>(
setLoading(true); setLoading(true);
setError(null); setError(null);
memoizedFetcher() fetcherRef
.current()
.then((result) => { .then((result) => {
if (!cancelled) { if (!cancelled) {
setEntry(cacheKey, result, maxSize); setEntry(cacheKey, result, maxSize);
@ -178,7 +181,8 @@ export function useCachedAsyncData<T>(
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [memoizedFetcher, cacheKey, ttl, maxSize]); // eslint-disable-next-line react-hooks/exhaustive-deps --- deps are explicitly managed by the caller
}, [...deps, cacheKey, ttl, maxSize]);
return { data, loading, error }; return { data, loading, error };
} }

View File

@ -113,7 +113,9 @@ export function useObjectSearchParams<TFilter, TOrderBy>(
// Snapshot ref — lets callbacks read the latest state without being // Snapshot ref — lets callbacks read the latest state without being
// recreated on every render (avoids infinite useCallback chains). // recreated on every render (avoids infinite useCallback chains).
const stateRef = useRef({ filters, sort, pageSize, pageIndex }); const stateRef = useRef({ filters, sort, pageSize, pageIndex });
stateRef.current = { filters, sort, pageSize, pageIndex }; useEffect(() => {
stateRef.current = { filters, sort, pageSize, pageIndex };
});
// Any filter/sort change resets pagination to the first page. // Any filter/sort change resets pagination to the first page.
const resetPagination = useCallback(() => { const resetPagination = useCallback(() => {

View File

@ -1,5 +1,5 @@
import { useSearchParams, Link } from "react-router"; import { useSearchParams, Link } from "react-router";
import { useCallback, useState, type ChangeEvent, type SubmitEvent } from "react"; import { useState, type ChangeEvent, type SubmitEvent } from "react";
import { Button } from "../components/ui/button"; import { Button } from "../components/ui/button";
import { Input } from "../components/ui/input"; import { Input } from "../components/ui/input";
import { Label } from "../components/ui/label"; import { Label } from "../components/ui/label";
@ -87,29 +87,26 @@ export default function Application() {
const [submitError, setSubmitError] = useState<string | null>(null); const [submitError, setSubmitError] = useState<string | null>(null);
const [submittedId, setSubmittedId] = useState<string | null>(null); const [submittedId, setSubmittedId] = useState<string | null>(null);
const handleSubmit = useCallback( const handleSubmit = async (e: SubmitEvent<HTMLFormElement>) => {
async (e: SubmitEvent<HTMLFormElement>) => { e.preventDefault();
e.preventDefault(); setSubmitError(null);
setSubmitError(null); setSubmitting(true);
setSubmitting(true); try {
try { const id = await createApplicationRecord({
const id = await createApplicationRecord({ Property__c: propertyId || null,
Property__c: propertyId || null, Status__c: "Submitted",
Status__c: "Submitted", User__c: contactId || user?.id || "",
User__c: contactId || user?.id || "", Start_Date__c: moveInDate.trim() || null,
Start_Date__c: moveInDate.trim() || null, Employment__c: employment.trim() || null,
Employment__c: employment.trim() || null, References__c: references.trim() || null,
References__c: references.trim() || null, });
}); setSubmittedId(id.id);
setSubmittedId(id.id); } catch (err) {
} catch (err) { setSubmitError(err instanceof Error ? err.message : "Failed to submit application.");
setSubmitError(err instanceof Error ? err.message : "Failed to submit application."); } finally {
} finally { setSubmitting(false);
setSubmitting(false); }
} };
},
[propertyId, contactId, moveInDate, employment, references, user?.id],
);
if (loading) { if (loading) {
return <ApplicationSkeleton />; return <ApplicationSkeleton />;

View File

@ -1,12 +1,12 @@
{ {
"name": "@salesforce/webapp-template-base-sfdx-project-experimental", "name": "@salesforce/webapp-template-base-sfdx-project-experimental",
"version": "1.120.6", "version": "1.128.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@salesforce/webapp-template-base-sfdx-project-experimental", "name": "@salesforce/webapp-template-base-sfdx-project-experimental",
"version": "1.120.6", "version": "1.128.0",
"license": "SEE LICENSE IN LICENSE.txt", "license": "SEE LICENSE IN LICENSE.txt",
"devDependencies": { "devDependencies": {
"@lwc/eslint-plugin-lwc": "^3.3.0", "@lwc/eslint-plugin-lwc": "^3.3.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "@salesforce/ui-bundle-template-base-sfdx-project", "name": "@salesforce/ui-bundle-template-base-sfdx-project",
"version": "1.120.6", "version": "1.128.0",
"description": "Base SFDX project template", "description": "Base SFDX project template",
"license": "SEE LICENSE IN LICENSE.txt", "license": "SEE LICENSE IN LICENSE.txt",
"publishConfig": { "publishConfig": {

View File

@ -101,5 +101,3 @@ console.log('UI bundle directory:', uiBundleDir);
run('npm install', 'npm', ['install', '--registry', 'https://registry.npmjs.org/'], { cwd: uiBundleDir }); run('npm install', 'npm', ['install', '--registry', 'https://registry.npmjs.org/'], { cwd: uiBundleDir });
run('npm run build', 'npm', ['run', 'build'], { cwd: uiBundleDir }); run('npm run build', 'npm', ['run', 'build'], { cwd: uiBundleDir });
console.log('\n--- Launching dev server (Ctrl+C to stop) ---\n');
run('npm run dev', 'npm', ['run', 'dev'], { cwd: uiBundleDir });