Skip to content

Instantly share code, notes, and snippets.

View karpolan's full-sized avatar
❤️
React + Node

Anton Karpenko karpolan

❤️
React + Node
View GitHub Profile
@karpolan
karpolan / redirect_www_add_index_html.js
Last active February 1, 2024 15:41
AWS CloudFront function for SPA, SSG and SEO. Redirects www URL to non-www URI, also adds missing `/index.html` to the link
/**
* Based on this thread https://github.com/aws-samples/amazon-cloudfront-functions/issues/11
*/
function getQueryParamsAsString(querystring) {
if (!querystring || querystring.length < 1) {
return ''; // There is no query params
}
const str = [];
for (const param in querystring) {
@karpolan
karpolan / useIsMobileNextJs.ts
Last active May 1, 2024 22:03
React useIsMobile() hook compatible with Next.js SSG/SSR
'use client';
import { useEffect, useState } from 'react';
import { useMediaQuery } from 'react-responsive';
export const IS_SERVER = typeof window === 'undefined';
export const MOBILE_SCREEN_MAX_WIDTH = 640;
export const SERVER_SIDE_MOBILE_FIRST = true; // true - for mobile, false - for desktop
/**
* Hook to detect isMobile vs. isDesktop using Media Query
@kriskarpenko
kriskarpenko / useQueryParams.js
Last active October 18, 2022 05:14
useQueryParams hook for React Router v6
import { useSearchParams } from "react-router-dom";
/**
* Hook to get all query params as key value pairs.
* Usage:
* const {param1, param2} = useQueryParams()
* const queryParams = useQueryParams()
* @returns {} object with all query params as key value pairs
*/
export function useQueryParams() {
@karpolan
karpolan / log.ts
Last active October 7, 2022 01:24
Simply logger for React App using TypeScript
const LOG_LEVEL_FROM_ENV = process?.env?.REACT_APP_LOG_LEVEL ?? 'silent';
/**
* Supported logging levels by names, the index is the level number.
*/
export const LOG_LEVEL_NAMES = ['trace', 'debug', 'info', 'warn', 'error', 'silent'];
/**
* Lightweight logger with minimal log level restrictions
* @class Log
@karpolan
karpolan / .prettierrc.js
Last active May 24, 2024 11:15
Prettier config for React App
module.exports = {
printWidth: 120, // max 120 chars in line, code is easy to read
useTabs: false, // use spaces instead of tabs
tabWidth: 2, // "visual width" of of the "tab"
trailingComma: 'es5', // add trailing commas in objects, arrays, etc.
semi: true, // add ; when needed
singleQuote: true, // '' for stings instead of ""
bracketSpacing: true, // import { some } ... instead of import {some} ...
arrowParens: 'always', // braces even for single param in arrow functions (a) => { }
jsxSingleQuote: false, // "" for react props, like in html
@karpolan
karpolan / loglevelAsConsole.js
Last active October 7, 2022 01:23
Extension for LogLevel npm (.time(), .endTime(), and so on)
import log from 'loglevel';
log.setLevel(process.env.LOG_LEVEL || process.env.REACT_APP_LOG_LEVEL || log.levels.ERROR);
log.info('log.level:', Object.keys(log.levels)[log.getLevel()]);
// Internal cache for time() and timeEnd() calls
const _timers = {};
/**
* Analog of console.time()
@karpolan
karpolan / ObjectAsList.js
Last active February 12, 2023 20:25
React component to print out <ul> list with all properties of JavaScript object
import { useMemo } from 'react';
const sortByAbc = ([a], [b]) => a.localeCompare(b);
const sortByZxy = ([a], [b]) => b.localeCompare(a);
const sortNone = () => 0;
/**
* Renders <ul> list with all properties of the given JavaScript object
* @param {object} object - object to print out
* @param {boolean} [sortAbc] - properties sorted A-Z when true
@sibelius
sibelius / withRouter.tsx
Created February 19, 2020 17:08
withRouter for react-router-dom v6
import { useHistory } from 'react-router-dom';
export const withRouter = (Component) => {
const Wrapper = (props) => {
const history = useHistory();
return (
<Component
history={history}
{...props}
@utilmind
utilmind / js-ucwords
Last active August 23, 2019 08:00
ucwords() for JavaScript
// The unicode-safe ucwords() func for JS (to capitalize the first characters of words),
// which additionally respects double-lastnames like Russian Засс-Ранцев and weird French names,
// like Honoré de Balzac and d'Artagnan.
String.prototype.ucwords = function() {
return this.toLowerCase()
.replace(/(^|\s|\-)[^\s$]/g, function(m) {
return m.toUpperCase();
})
// French, Arabic and some noble names...
@karpolan
karpolan / withSuspense.js
Created August 10, 2019 10:46
withSuspense() HOC for React.lazy() + React.Suspense
import React from 'react';
import { CircularProgress, LinearProgress } from '@material-ui/core/';
/**
* Wraps the React Component with React.Suspense and FallbackComponent while loading.
* @param {React.Component} WrappedComponent - lazy loading component to wrap.
* @param {React.Component} FallbackComponent - component to show while the WrappedComponent is loading.
*/
export const withSuspense = (WrappedComponent, FallbackComponent = null) => {
return class extends React.Component {