Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dist/ccdb5.css

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dist/ccdb5.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/ccdb5.js.LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
*/

/**
* react-router v7.8.2
* react-router v7.9.1
*
* Copyright (c) Remix Software Inc.
*
Expand Down
54 changes: 25 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,49 +33,45 @@
"preview": "rsbuild preview"
},
"devDependencies": {
"@babel/cli": "^7.28.0",
"@babel/core": "^7.28.0",
"@babel/eslint-parser": "^7.28.0",
"@babel/core": "^7.28.4",
"@babel/eslint-parser": "^7.28.4",
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
"@babel/preset-env": "^7.28.3",
"@babel/preset-react": "^7.27.1",
"@babel/runtime": "^7.27.6",
"@cfpb/browserslist-config": "0.0.4",
"@cfpb/cfpb-design-system": "^4.0.1",
"@csstools/postcss-sass": "^5.1.1",
"@csstools/sass-import-resolve": "^1.0.0",
"@reduxjs/toolkit": "^2.8.2",
"@rsbuild/core": "^1.5.3",
"@cfpb/cfpb-design-system": "^4.0.4",
"@eslint/js": "^9.35.0",
"@reduxjs/toolkit": "^2.9.0",
"@rsbuild/core": "^1.5.9",
"@rsbuild/plugin-react": "^1.4.0",
"@rsbuild/plugin-sass": "^1.4.0",
"@rsbuild/plugin-svgr": "^1.2.2",
"@testing-library/cypress": "^10.0.2",
"@testing-library/cypress": "^10.1.0",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
"@testing-library/react-hooks": "^8.0.0",
"@testing-library/user-event": "^14.5.2",
"autoprefixer": "^10.4.20",
"babel-jest": "^30.1.2",
"babel-plugin-module-resolver": "^5.0.2",
"britecharts": "git+https://github.com/cfpb/britecharts.git#v2.4.3",
"coveralls": "^3.1.1",
"cypress": "^14.5.1",
"cypress": "^15.2.0",
"d3": "^7.9.0",
"dayjs": "^1.11.18",
"eslint": "^9.34.0",
"eslint": "^9.35.0",
"eslint-config-prettier": "^10.1.5",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-cypress": "^5.1.1",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^29.0.1",
"eslint-plugin-jest-dom": "^5.5.0",
"eslint-plugin-jsdoc": "^54.2.1",
"eslint-plugin-jsdoc": "^59.0.1",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-redux": "^4.2.2",
"eslint-plugin-testing-library": "^7.6.7",
"globals": "^16.3.0",
"eslint-plugin-testing-library": "^7.8.0",
"globals": "^16.4.0",
"highcharts": "11.4.8",
"history": "^5.3.0",
"husky": "^9.1.7",
Expand All @@ -85,31 +81,26 @@
"jest": "^30.1.3",
"jest-environment-jsdom": "^30.1.2",
"jest-fetch-mock": "^3.0.3",
"jest-watch-typeahead": "^3.0.1",
"lint-staged": "^16.1.6",
"lodash": "^4.17.21",
"module-resolver": "^1.0.0",
"postcss": "^8.5.6",
"postcss-preset-env": "^10.3.1",
"postcss-safe-parser": "^7.0.0",
"postcss-scss": "^4.0.9",
"prettier": "^3.6.2",
"prop-types": "^15.5.10",
"query-string": "^9.2.2",
"query-string": "^9.3.1",
"react": "^18.3.1",
"react-bootstrap": "^2.10.10",
"react-bootstrap-typeahead": "^6.4.1",
"react-dom": "^18.3.1",
"react-fast-compare": "^3.2.2",
"react-modal": "^3.16.1",
"react-redux": "^9.2.0",
"react-router": "^7.8.2",
"release-it": "^19.0.3",
"sass": "^1.91.0",
"react-router": "^7.9.1",
"release-it": "^19.0.5",
"sass": "^1.92.1",
"string-replace-loader": "^3.2.0",
"stylelint": "^16.23.0",
"stylelint": "^16.24.0",
"stylelint-config-standard": "^39.0.0",
"stylelint-config-standard-scss": "^15.0.1"
"stylelint-config-standard-scss": "^16.0.0"
},
"lint-staged": {
"src/**/*.{css,scss}": [
Expand All @@ -126,5 +117,10 @@
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"dependencies": {}
"dependencies": {},
"resolutions": {
"d3-color": "3.1.0",
"form-data": "4.0.4",
"tough-cookie": "4.1.3"
}
}
2 changes: 1 addition & 1 deletion src/actions/analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Analytics = {
* @param {string} action - Name of event.
* @param {string} label - DOM element label.
* @param {string} category - Type of event.
* @param {Function} callback - Function to call on GTM submission.
* @param {() => void} [callback] - Callback to call on GTM submission.
* @param {number} timeout - Callback invocation fallback time.
* @returns {object} Data layer object.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/actions/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function normalizeRouteParams(params) {
*
* @param {string} path - the new path being used
* @param {object} params - the query string
* @returns {Function} a series of actions to execute
* @returns {(next: import('../types/reduxTypes').ReduxTypes.Next) => (action: import('../types/reduxTypes').ReduxTypes.PlainAction | import('../types/reduxTypes').ReduxTypes.Thunk) => Promise<unknown>} A Redux middleware function
*/
export function changeRoute(path, params) {
return function (dispatch, getState) {
Expand Down
8 changes: 4 additions & 4 deletions src/components/Map/TileChartMap/TileMap/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function makeShortName(value) {
* helper function to get the bins for legend and colors, etc.
*
* @param {Array} quantiles - floats that mark the max of each range
* @param {Function} scale - scaling function for color
* @param {function(number): string} scale - scaling function for color
* @returns {Array} the bins with bounds, name, and color
*/
export function getBins(quantiles, scale) {
Expand Down Expand Up @@ -93,7 +93,7 @@ export function getBins(quantiles, scale) {
* helper function to get the Per 1000 population bins for legend and colors
*
* @param {Array} quantiles - floats that mark the max of each range
* @param {Function} scale - scaling function for color
* @param {function(number): string} scale - scaling function for color
* @returns {Array} the bins with bounds, name, and color
*/
export function getPerCapitaBins(quantiles, scale) {
Expand Down Expand Up @@ -126,7 +126,7 @@ export function getPerCapitaBins(quantiles, scale) {
Utility Functions 2 */
/**
* @param {object} data - Data to process. add in state paths to the data obj
* @param {Function} scale - scaling function for color
* @param {function(number): string} scale - scaling function for color
* @returns {object} The processed data.
*/
export function processMapData(data, scale) {
Expand Down Expand Up @@ -170,7 +170,7 @@ export function processMapData(data, scale) {
* color. This helps the "only three values" case
*
* @param {number} value - the number of complaints or perCapita
* @param {Function} scale - scaling function for color
* @param {function(number): string} scale - scaling function for color
* @returns {string} color hex or rgb code for a color
*/
export function getColorByValue(value, scale) {
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useEffect } from 'react';
* https://atomizedobjects.com/blog/react/add-event-listener-react-hooks/
*
* @param {string} event - event to listen to
* @param {Function} handler - function to run
* @param {(e: Event) => void} handler - function to run
* @param {boolean} passive - if true, means function will never call preventDefault
*/
export function useEvent(event, handler, passive = false) {
Expand Down
4 changes: 2 additions & 2 deletions src/middleware/actionLogger/actionLogger.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { addAction } from '../../reducers/actions/actionsSlice';
* When triggered, the function will keep checking if the bulk process is pending
* and indicate when the process is finished
*
* @param {object} store - Redux store
* @returns {Function} a closure around the Redux middleware function
* @param {import('../types/reduxTypes').ReduxTypes.Store} store - Redux store
* @returns {(next: import('../types/reduxTypes').ReduxTypes.Next) => (action: import('../types/reduxTypes').ReduxTypes.PlainAction | import('../types/reduxTypes').ReduxTypes.Thunk) => Promise<unknown>} A Redux middleware function
*/
export const actionLogger = (store) => (next) => async (action) => {
if (typeof action === 'function') {
Expand Down
5 changes: 3 additions & 2 deletions src/middleware/synchUrl/synchUrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,10 @@ export function extractQueryStringParams(state) {
}

/**
* Middleware function to synch state to url
*
* @param {object} store - This is the redux store.
* @returns {Function} a closure around the Redux middleware function
* @param {import('../types/reduxTypes').ReduxTypes.Store} store - Redux store
* @returns {(next: import('../types/reduxTypes').ReduxTypes.Next) => (action: import('../types/reduxTypes').ReduxTypes.PlainAction | import('../types/reduxTypes').ReduxTypes.Thunk) => Promise<unknown>} A Redux middleware function
*/
const synchUrl = (store) => (next) => (action) => {
// Pass the action forward in the chain
Expand Down
3 changes: 1 addition & 2 deletions src/reducers/trends/trendsSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,7 @@ function processAreaData(state, aggregations) {
* @param {object} aggregations - comes from the API
* @param {string} focus - if a focus item was selected
* @param {string} subLens - current subLens
* @returns {{dataByTopic: ([{dashed: boolean, show: boolean, topic: string,
* topicName: string, dates: *}]|[])}} theformatted object containing line info
* @returns {{dataByTopic: ([{dashed: boolean, show: boolean, topic: string, topicName: string, dates: object[]}]|[])}} the formatted object containing line info
*/
function processLineData(lens, aggregations, focus, subLens) {
const areaBuckets = aggregations.dateRangeArea.dateRangeArea.buckets;
Expand Down
53 changes: 53 additions & 0 deletions src/types/reduxTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* @file Redux-related shared JSDoc typedefs (namespaced)
*/

/**
* @namespace ReduxTypes
*/

/**
* A plain Redux action.
*
* @typedef {object} ReduxTypes.PlainAction
* @property {string} type - the type of the action
* @property {unknown} [payload] - the payload of the action
* @property {unknown} [error] - any error
* @property {unknown} [meta] - any meta data
* @property {Record<string, unknown>} [extra] - Any additional fields
*/

/**
* A Redux thunk function.
*
* @typedef {(dispatch: ReduxTypes.Dispatch, getState: ReduxTypes.GetState) => unknown} ReduxTypes.Thunk
*/

/**
* Redux dispatch that can handle plain actions or thunks.
*
* @typedef {(action: ReduxTypes.PlainAction | ReduxTypes.Thunk) => unknown} ReduxTypes.Dispatch
*/

/**
* Redux getState function.
*
* @typedef {() => unknown} ReduxTypes.GetState
*/

/**
* The `next` function in the middleware chain (accepts only plain actions).
*
* @typedef {(action: ReduxTypes.PlainAction) => unknown} ReduxTypes.Next
*/

/**
* Minimal Redux store shape used by middleware.
*
* @typedef {object} ReduxTypes.Store
* @property {ReduxTypes.Dispatch} dispatch - the dispatch function from redux
* @property {ReduxTypes.GetState} getState - the getState function from redux
*/

// Make this a module so `import()` type references work.
export {};
10 changes: 0 additions & 10 deletions src/utils/compare.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,3 @@ export const arrayEquals = (first, second) => {
}
return true;
};

/**
* Function to compare two objects or arrays.
*
* @param {object | Array | any} first - value 1 to convert to string
* @param {object | Array | any} second - value 2 to convert to string to compare
* @returns {boolean} Whether the values are equal
*/
export const isEqual = (first, second) =>
JSON.stringify(first) === JSON.stringify(second);
32 changes: 0 additions & 32 deletions src/utils/compare.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,3 @@ describe('arrayEquals', () => {
expect(res).toBeFalsy();
});
});

describe('isEqual', () => {
it('compares different length arrays', () => {
const res = sut.isEqual([], [1, 2]);
expect(res).toBeFalsy();
});

it('compares equal arrays', () => {
const res = sut.isEqual([1, 2], [1, 2]);
expect(res).toBeTruthy();
});

it('compares unsorted arrays', () => {
const res = sut.isEqual([2, 1], [1, 2]);
expect(res).toBeFalsy();
});

it('compares arrays with different values', () => {
const res = sut.isEqual([2, 2], [1, 2]);
expect(res).toBeFalsy();
});

it('compares different objects', () => {
const res = sut.isEqual({}, { foo: 1 });
expect(res).toBeFalsy();
});

it('compares equal objects', () => {
const res = sut.isEqual({ foo: 1 }, { foo: 1 });
expect(res).toBeTruthy();
});
});
17 changes: 9 additions & 8 deletions src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@ export const clamp = (number, boundOne, boundTwo) => {
};

/**
* Function to set the limit of the range of a set of dates
* Function to limit the range (max/min) of a set of dates
*
* @param {string} val - value we are checking
* @param {string} min - smallest number it can be
* @param {string} max - biggest number it can be
* @returns {*} the limited value
* @param {string} min - earliest date it can be
* @param {string} max - oldest date it can be
* @returns {Date} the limited value
*/
export const clampDate = (val, min, max) => {
let xDate = new Date(val);
Expand Down Expand Up @@ -364,10 +364,11 @@ export function startOfToday() {
* Native implementation of lodash debounce
* https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_debounce
*
* @param {Function} func - The function to run.
* @template {(...args: unknown[]) => unknown} F
* @param {F} func - The function to run.
* @param {number} wait - Time in milliseconds.
* @param {boolean} immediate - Whether we should run function immedately.
* @returns {Function} the debounced function
* @param {boolean} [immediate] - Whether we should run function immediately.
* @returns {(...args: Parameters<F>) => void} The debounced function
*/
export function debounce(func, wait, immediate) {
let timeout;
Expand Down Expand Up @@ -469,7 +470,7 @@ export const processUrlArrayParams = (params, state, arrayParams) => {
*
* @param {string} filterKey - the filter 'Debt'
* @param {Array} subitems - the buckets to process to generate slug
* @returns {Set<any>} returns a set of uniques Debt, Debt*Foo
* @returns {Set<string>} returns a set of uniques Debt, Debt*Foo
*/
export const getAllFilters = (filterKey, subitems) => {
const values = new Set();
Expand Down
2 changes: 1 addition & 1 deletion src/utils/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { getSubLens } from './trends';
*
* @param {string|number} value - input val to check
* @param {string} field - key of the query object we need to validate
* @returns {string|number|*} valid value
* @returns {string|number|unknown} valid value
Copy link
Member

@anselmbradford anselmbradford Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Should this be undefined instead of unknown?

*/
export const enforceValues = (value, field) => {
const valMap = {
Expand Down
Loading