Skip to content

Commit 4d297c0

Browse files
authored
refactor: replace index files with named files for improved clarity and maintainability TCKT-404 (#633)
* refactor: replace index files with named files for improved clarity and maintainability TCKT-404 * docs: add ADR for using named exports and avoiding index files TCKT-404
1 parent 1b2b065 commit 4d297c0

126 files changed

Lines changed: 313 additions & 294 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# ADR 0017: Use Named Exports Over Default Exports and Avoid index Files
2+
3+
Date: 04-16-2025
4+
5+
## Status
6+
Approved
7+
8+
## Context
9+
During the recent refactoring of the `Form` and `FormManager` components in the `design` package, we noticed inconsistencies in the use of default exports, named exports, and `index` files. Some files used default exports, while others used named exports. Additionally, many directories relied on `index.tsx` files, which made it harder to locate specific components or utilities in the codebase.
10+
11+
Default exports can sometimes lead to ambiguity, especially when renaming imports, and they do not provide the same level of tooling support (e.g., auto-imports in IDEs) as named exports. Named exports, on the other hand, make it clear what is being exported and allow for more consistent imports across the codebase.
12+
13+
Similarly, `index` files can introduce ambiguity when navigating the codebase, as multiple `index.tsx` files across different directories make it harder to locate specific functionality. Using descriptive file names improves clarity and maintainability.
14+
15+
## Decision
16+
We will adopt the following guidelines for exports and file structure moving forward:
17+
1. **Use named exports** for all components, utilities, and types.
18+
2. **Avoid default exports**, except in cases where a file exports a single, primary entity (e.g., a React component that represents the main purpose of the file).
19+
3. **Avoid `index` files** in favor of descriptive file names (e.g., `FormManager.tsx` instead of `index.tsx`).
20+
21+
## Consequences
22+
- **Consistency:** The codebase will have a consistent export style and file structure, making it easier to read and maintain.
23+
- **Tooling Support:** Named exports improve IDE tooling, such as auto-imports and refactoring.
24+
- **Clarity:** Named exports and descriptive file names make it clear what is being exported and where functionality resides, reducing ambiguity.
25+
- **Ease of Navigation:** Avoiding `index` files ensures that file names are descriptive, making it easier to locate specific components or utilities.
26+
27+
## Examples
28+
### Before (Default Export):
29+
```tsx
30+
// FormManager.tsx
31+
export default function FormManager() { ... }
32+
33+
// Importing in other files
34+
import FormManager from './FormManager';
35+
```
36+
37+
### After (Named Export):
38+
```tsx
39+
// FormManager.tsx
40+
export function FormManager() { ... }
41+
42+
// Importing in other files
43+
import { FormManager } from './FormManager';
44+
```
45+
46+
## Related Changes
47+
This decision was applied during the refactoring of the `Form` and `FormManager` components in the design package. As part of this refactor:
48+
49+
- Default exports were replaced with named exports.
50+
- `index.tsx` files were replaced with descriptive file names (e.g., `FormManager.tsx`, `PatternComponents.tsx`).

packages/design/src/Form/Form.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import type { Meta, StoryObj } from '@storybook/react';
33

4-
import Form from './index.js';
4+
import Form from './Form.js';
55
import { createTestFormContext, createTestSession } from '../test-form.js';
66
import { MemoryRouter } from 'react-router-dom';
77

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,10 @@ import {
88
type FormConfig,
99
type FormRoute,
1010
type FormSession,
11-
type PatternProps,
1211
type Prompt,
13-
type PromptComponent,
1412
} from '@gsa-tts/forms-core';
1513
import { renderPromptComponents } from './form-common.js';
16-
17-
export type FormUIContext = {
18-
config: FormConfig;
19-
components: ComponentForPattern;
20-
uswdsRoot: `${string}/`;
21-
};
22-
23-
export type ComponentForPattern<T extends PatternProps = PatternProps> = Record<
24-
string,
25-
PatternComponent<T>
26-
>;
27-
28-
export type PatternComponent<T extends PatternProps = PatternProps<unknown>> =
29-
React.ComponentType<
30-
T & {
31-
context: FormUIContext;
32-
childComponents?: PromptComponent[];
33-
}
34-
>;
14+
import { FormUIContext } from './types.js';
3515

3616
const usePrompt = (
3717
initialPrompt: Prompt,

packages/design/src/Form/components/AccordionRow/AccordionRow.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { type Meta, type StoryObj } from '@storybook/react';
33

4-
import AccordionRow from './index.js';
4+
import AccordionRow from './AccordionRow.js';
55

66
const meta: Meta<typeof AccordionRow> = {
77
title: 'patterns/AccordionRow',

packages/design/src/Form/components/AccordionRow/index.tsx renamed to packages/design/src/Form/components/AccordionRow/AccordionRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
22
import classNames from 'classnames';
33

44
import { type AccordionRowProps } from '@gsa-tts/forms-core';
5-
import { type PatternComponent } from '../../index.js';
5+
import { type PatternComponent } from '../../types.js';
66

77
const AccordionRow: PatternComponent<AccordionRowProps> = ({
88
inputId,

packages/design/src/Form/components/Address/Address.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { FormProvider, useForm } from 'react-hook-form';
33
import { type Meta, type StoryObj } from '@storybook/react';
44

5-
import AddressPattern from './index.js';
5+
import AddressPattern from './Address.js';
66
import { stateTerritoryOrMilitaryPostList } from '@gsa-tts/forms-core';
77

88
const meta: Meta<typeof AddressPattern> = {

packages/design/src/Form/components/Address/index.tsx renamed to packages/design/src/Form/components/Address/Address.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useFormContext } from 'react-hook-form';
44

55
import { type AddressComponentProps } from '@gsa-tts/forms-core';
66

7-
import { type PatternComponent } from '../../index.js';
7+
import { type PatternComponent } from '../../types.js';
88

99
const AddressPattern: PatternComponent<AddressComponentProps> = ({
1010
childProps,

packages/design/src/Form/components/Attachment/Attachment.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { type AttachmentProps } from '@gsa-tts/forms-core';
66
import { FormProvider, useForm } from 'react-hook-form';
77
import type { Meta, StoryObj } from '@storybook/react';
88

9-
import Attachment from './index.js';
9+
import Attachment from './Attachment.js';
1010

1111
const defaultArgs = {
1212
_patternId: '',

packages/design/src/Form/components/Attachment/index.tsx renamed to packages/design/src/Form/components/Attachment/Attachment.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React, { useState } from 'react';
33
import { useFormContext } from 'react-hook-form';
44
import { type AttachmentProps } from '@gsa-tts/forms-core';
55
import { attachmentFileTypeOptions } from '@gsa-tts/forms-core';
6-
import { type PatternComponent } from '../../../Form/index.js';
6+
import { type PatternComponent } from '../../types.js';
77

88
const Attachment: PatternComponent<AttachmentProps> = props => {
99
const { register } = useFormContext();

packages/design/src/Form/components/Checkbox/Checkbox.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { FormProvider, useForm } from 'react-hook-form';
33
import { type Meta, type StoryObj } from '@storybook/react';
44

5-
import { CheckboxPattern } from './Checkbox.js';
5+
import CheckboxPattern from './Checkbox.js';
66
import { CheckboxProps } from '@gsa-tts/forms-core';
77

88
const meta: Meta<typeof CheckboxPattern> = {

0 commit comments

Comments
 (0)