Skip to content

Commit

Permalink
chore: refactor lodash and radix imports (#3373)
Browse files Browse the repository at this point in the history
* chore: refactor lodash and radix imports

* chore: clean up
  • Loading branch information
zchenwei authored Feb 1, 2023
1 parent 1db2894 commit ec881c6
Show file tree
Hide file tree
Showing 18 changed files with 84 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
InAppMessageInteractionEvent,
Notifications,
} from '@aws-amplify/notifications';
import isNil from 'lodash/isNil.js';
import { isNil } from '@aws-amplify/ui';

import { RenderNothing } from '../../../components';
import { useInAppMessaging } from '../useInAppMessaging';
Expand Down
3 changes: 1 addition & 2 deletions packages/react-core/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import isEmpty from 'lodash/isEmpty.js';
import { isObject, isString } from '@aws-amplify/ui';
import { isEmpty, isObject, isString } from '@aws-amplify/ui';

function isEmptyArray<T>(value: T): boolean {
return Array.isArray(value) && isEmpty(value);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import isEqual from 'lodash/isEqual.js';

import { Logger } from 'aws-amplify';
import {
Expand All @@ -9,6 +8,7 @@ import {
getDefaultPasswordValidators,
runFieldValidators,
translate,
isEqual,
} from '@aws-amplify/ui';

import { useAuth } from '../../../internal';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useMemo, useRef } from 'react';
import isEmpty from 'lodash/isEmpty.js';

import { isEmpty } from '@aws-amplify/ui';
import { MessageComponentBaseProps } from '@aws-amplify/ui-react-core';

import { useMessageImage } from '../useMessageImage';
Expand Down
17 changes: 9 additions & 8 deletions packages/react/src/components/ThemeProvider/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import * as React from 'react';
import * as RadixDirection from '@radix-ui/react-direction';

import { createTheme, Theme, WebTheme } from '@aws-amplify/ui';
import {
createTheme,
Theme,
WebTheme,
sanitizeNamespaceImport,
} from '@aws-amplify/ui';

import { AmplifyContext } from './AmplifyContext';

// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR),
// the module will be imported as CommonJS module, in which we have to reference the `default`
let sanitizedRadixDirection = { default: undefined, ...RadixDirection };
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
sanitizedRadixDirection =
sanitizedRadixDirection.default ?? sanitizedRadixDirection;
const { DirectionProvider } = sanitizedRadixDirection;
// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR)
// We have to use namespace import and sanitize it to ensure the interoperablity between ESM and CJS
const { DirectionProvider } = sanitizeNamespaceImport(RadixDirection);

export type ColorMode = 'system' | 'light' | 'dark';
export type Direction = 'ltr' | 'rtl';
Expand Down
3 changes: 2 additions & 1 deletion packages/react/src/primitives/Collection/Collection.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import classNames from 'classnames';
import debounce from 'lodash/debounce.js';
import * as React from 'react';

import { debounce } from '@aws-amplify/ui';

import { Flex } from '../Flex';
import { Grid } from '../Grid';
import { Text } from '../Text';
Expand Down
12 changes: 5 additions & 7 deletions packages/react/src/primitives/Expander/Expander.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@ import * as React from 'react';
import * as Accordion from '@radix-ui/react-accordion';
import classNames from 'classnames';

import { useDeprecationWarning } from '../../hooks/useDeprecationWarning';
import { sanitizeNamespaceImport } from '@aws-amplify/ui';

import { useDeprecationWarning } from '../../hooks/useDeprecationWarning';
import { ComponentClassNames } from '../shared/constants';
import { ExpanderProps } from '../types/expander';
import { Primitive } from '../types/view';
import { splitPrimitiveProps } from '../utils/splitPrimitiveProps';

// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR),
// the module will be imported as CommonJS module, in which we have to reference the `default`
let sanitizedAccordion = { default: undefined, ...Accordion };
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
sanitizedAccordion = sanitizedAccordion.default ?? sanitizedAccordion;
const { Root } = sanitizedAccordion;
// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR)
// We have to use namespace import and sanitize it to ensure the interoperablity between ESM and CJS
const { Root } = sanitizeNamespaceImport(Accordion);

const ExpanderPrimitive: Primitive<ExpanderProps, 'div'> = (
{
Expand Down
11 changes: 5 additions & 6 deletions packages/react/src/primitives/Expander/ExpanderItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as React from 'react';
import * as Accordion from '@radix-ui/react-accordion';
import classNames from 'classnames';

import { sanitizeNamespaceImport } from '@aws-amplify/ui';

import { ComponentClassNames } from '../shared/constants';
import { ExpanderItemProps } from '../types/expander';
import { IconExpandMore } from '../Icon/internal';
Expand All @@ -10,12 +12,9 @@ import { splitPrimitiveProps } from '../utils/splitPrimitiveProps';
import { useStableId } from '../utils/useStableId';
import { View } from '../View';

// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR),
// the module will be imported as CommonJS module, in which we have to reference the `default`
let sanitizedAccordion = { default: undefined, ...Accordion };
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
sanitizedAccordion = sanitizedAccordion.default ?? sanitizedAccordion;
const { Item, Header, Trigger, Content } = sanitizedAccordion;
// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR)
// We have to use namespace import and sanitize it to ensure the interoperablity between ESM and CJS
const { Item, Header, Trigger, Content } = sanitizeNamespaceImport(Accordion);

export const EXPANDER_ITEM_TEST_ID = 'expander-item';
export const EXPANDER_HEADER_TEST_ID = 'expander-header';
Expand Down
11 changes: 5 additions & 6 deletions packages/react/src/primitives/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@ import * as React from 'react';
import classNames from 'classnames';
import * as Dropdown from '@radix-ui/react-dropdown-menu';

import { sanitizeNamespaceImport } from '@aws-amplify/ui';

import { ButtonGroup } from '../ButtonGroup';
import { ComponentClassNames } from '../shared/constants';
import { IconMenu } from '../Icon/internal';
import { MenuButton } from './MenuButton';
import { MenuProps, Primitive } from '../types';

// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR),
// the module will be imported as CommonJS module, in which we have to reference the `default`
let sanitizedDropdown = { default: undefined, ...Dropdown };
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
sanitizedDropdown = sanitizedDropdown.default ?? sanitizedDropdown;
// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR)
// We have to use namespace import and sanitize it to ensure the interoperablity between ESM and CJS
const { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent } =
sanitizedDropdown;
sanitizeNamespaceImport(Dropdown);

export const MENU_TRIGGER_TEST_ID = 'amplify-menu-trigger-test-id';
export const MENU_ITEMS_GROUP_TEST_ID = 'amplify-menu-items-group-test-id';
Expand Down
11 changes: 5 additions & 6 deletions packages/react/src/primitives/Menu/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ import * as React from 'react';
import classNames from 'classnames';
import * as Dropdown from '@radix-ui/react-dropdown-menu';

import { sanitizeNamespaceImport } from '@aws-amplify/ui';

import { ComponentClassNames } from '../shared/constants';
import { MenuButton } from './MenuButton';
import { MenuItemProps } from '../types';

// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR),
// the module will be imported as CommonJS module, in which we have to reference the `default`
let sanitizedDropdown = { default: undefined, ...Dropdown };
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
sanitizedDropdown = sanitizedDropdown.default ?? sanitizedDropdown;
const { DropdownMenuItem } = sanitizedDropdown;
// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR)
// We have to use namespace import and sanitize it to ensure the interoperablity between ESM and CJS
const { DropdownMenuItem } = sanitizeNamespaceImport(Dropdown);

export const MENU_ITEM_TEST_ID = 'amplify-menu-item-test-id';

Expand Down
11 changes: 5 additions & 6 deletions packages/react/src/primitives/SliderField/SliderField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import classNames from 'classnames';
import * as RadixSlider from '@radix-ui/react-slider';
import * as React from 'react';

import { sanitizeNamespaceImport } from '@aws-amplify/ui';

import { classNameModifier } from '../shared/utils';
import { ComponentClassNames } from '../shared/constants';
import { FieldDescription, FieldErrorMessage } from '../Field';
Expand All @@ -15,12 +17,9 @@ import { splitPrimitiveProps } from '../utils/splitPrimitiveProps';
import { View } from '../View';
import { useStableId } from '../utils/useStableId';

// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR),
// the module will be imported as CommonJS module, in which we have to reference the `default`
let sanitizedRadixSlider = { default: undefined, ...RadixSlider };
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
sanitizedRadixSlider = sanitizedRadixSlider.default ?? sanitizedRadixSlider;
const { Range, Root, Thumb, Track } = sanitizedRadixSlider;
// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR)
// We have to use namespace import and sanitize it to ensure the interoperablity between ESM and CJS
const { Range, Root, Thumb, Track } = sanitizeNamespaceImport(RadixSlider);

export const SLIDER_LABEL_TEST_ID = 'slider-label';
export const SLIDER_ROOT_TEST_ID = 'slider-root';
Expand Down
16 changes: 10 additions & 6 deletions packages/react/src/primitives/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ import classNames from 'classnames';
import * as RadixTabs from '@radix-ui/react-tabs';
import * as React from 'react';

import { sanitizeNamespaceImport } from '@aws-amplify/ui';

import { ComponentClassNames } from '../shared/constants';
import { Flex } from '../Flex';
import { TabsProps, TabsSpacing, TabItemProps, Primitive } from '../types';
import { View } from '../View';

// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR),
// the module will be imported as CommonJS module, in which we have to reference the `default`
let sanitizedRadixTabs = { default: undefined, ...RadixTabs };
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
sanitizedRadixTabs = sanitizedRadixTabs.default ?? sanitizedRadixTabs;
const { Root, List, Trigger: RadixTab, Content: Panel } = sanitizedRadixTabs;
// Radix packages don't support ESM in Node, in some scenarios(e.g. SSR)
// We have to use namespace import and sanitize it to ensure the interoperablity between ESM and CJS
const {
Root,
List,
Trigger: RadixTab,
Content: Panel,
} = sanitizeNamespaceImport(RadixTabs);

/**
* `TabItemProps` does not include HTML data attributes, so `data-spacing` is added explicitly
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/helpers/authenticator/context.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/**
* This file contains helpers that process authenticator state machine context
*/
import includes from 'lodash/includes.js';

import {
LoginMechanismArray,
AuthContext,
AuthMachineState,
} from '../../types';
import { includes } from '../../utils';

export const getPrimaryAlias = (state: AuthMachineState) => {
const loginMechanisms = state?.context.config?.loginMechanisms;
Expand Down
5 changes: 2 additions & 3 deletions packages/ui/src/machines/authenticator/actors/signIn.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Auth } from 'aws-amplify';
import get from 'lodash/get.js';
import isEmpty from 'lodash/isEmpty.js';
import { createMachine, sendUpdate } from 'xstate';

import {
AuthChallengeName,
AuthEvent,
Expand Down Expand Up @@ -34,8 +33,8 @@ import {
setUser,
setUsernameAuthAttributes,
} from '../actions';

import { defaultServices } from '../defaultServices';
import { get, isEmpty } from '../../../utils';

export type SignInMachineOptions = {
services?: Partial<typeof defaultServices>;
Expand Down
3 changes: 1 addition & 2 deletions packages/ui/src/machines/authenticator/signUp.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { Auth } from 'aws-amplify';
import get from 'lodash/get.js';
import pickBy from 'lodash/pickBy.js';
import { assign, createMachine, sendUpdate } from 'xstate';

import { AuthEvent, SignUpContext } from '../../types';
Expand All @@ -21,6 +19,7 @@ import {
handleSubmit,
} from './actions';
import { defaultServices } from './defaultServices';
import { get, pickBy } from '../../utils';

export type SignUpMachineOptions = {
services?: Partial<typeof defaultServices>;
Expand Down
11 changes: 2 additions & 9 deletions packages/ui/src/theme/utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import has from 'lodash/has.js';
import kebabCase from 'lodash/kebabCase.js';

// internal style dictionary function
import usesReference from 'style-dictionary/lib/utils/references/usesReference.js';

import { isObject, isString } from '../utils';
import {
DesignToken,
ShadowValue,
WebDesignToken,
} from './tokens/types/designToken';
import { isObject, isString, has, kebabCase } from '../utils';
import { ShadowValue, WebDesignToken } from './tokens/types/designToken';

type ShadowPropertyKey = keyof Exclude<ShadowValue, string>;

Expand Down
26 changes: 26 additions & 0 deletions packages/ui/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
/**
* We re-export any lodash imports to avoid appending .js extension across codebase
* The ultimate goal is have replacement implementation to remove the entire dependency
*/
export { default as isEqual } from 'lodash/isEqual.js';
export { default as isEmpty } from 'lodash/isEmpty.js';
export { default as debounce } from 'lodash/debounce.js';
export { default as isNil } from 'lodash/isNil.js';
export { default as includes } from 'lodash/includes.js';
export { default as get } from 'lodash/get.js';
export { default as pickBy } from 'lodash/pickBy.js';
export { default as has } from 'lodash/has.js';
export { default as kebabCase } from 'lodash/kebabCase.js';
export { default as merge } from 'lodash/merge.js';

/**
* Some libraries may not follow Node ES module spec and could be loaded as CommonJS modules,
* To ensure the interoperability between ESM and CJS, modules from those libraries have to be loaded via namespace import
* And sanitized by the function below because unlike ESM namespace, CJS namespace set `module.exports` object on the `default` key
* https://nodejs.org/api/esm.html#interoperability-with-commonjs
*/
export const sanitizeNamespaceImport = <T>(namespaceModule: T): T => {
const sanitizedNamespaceModule = { default: undefined, ...namespaceModule };
return sanitizedNamespaceModule.default ?? sanitizedNamespaceModule;
};

/**
* Checks if `value` is an Object (non-primitive, non-array, non-function)
* Will return false for Arrays and functions
Expand Down
3 changes: 1 addition & 2 deletions packages/ui/src/validators/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { AuthFormData, PasswordSettings, Validator } from '../types';
import isEmpty from 'lodash/isEmpty.js';
import merge from 'lodash/merge.js';
import { isEmpty, merge } from '../utils';

// Runs all validators given. Resolves if there are no error. Rejects otherwise.
export const runValidators = async (
Expand Down

0 comments on commit ec881c6

Please sign in to comment.