Directory Structure

Component Library Hierarchy

The directory structure of the Component Library is governed by several rules that explicitly inform the names of files and where within the library they should be located. Several examples are provided below, using dummy components, to illustrate how component files are arranged in different scenarios.

elentra-2x-js/src/components

elentra-2x-js/src/components
components/

├──	LoneComponent/
│	└──	LoneComponent.vue

├──	ComponentWithExternalStyles/
│	├──	ComponentWithExternalStyles.vue
│	└──	style.scss

├──	ComponentWithLocalTypeScript/
│	├──	ComponentWithLocalTypeScript.vue
│	└──	index.ts

├──	ComponentWithLocalEnums/
│	├──	ComponentWithLocalEnums.vue
│	└──	types.ts

├──	ComponentWithAbstractClasses/
│	├──	abstracts/
│	│   ├── ExampleAbstractClassOne.ts
│	│   └── ExampleAbstractClassTwo.ts
│	└──	ComponentWithAbstractClasses.vue

├──	ComponentWithInterfaces/
│	├──	interfaces/
│	│   ├── ExampleInterfaceOne.ts
│	│   └── ExampleInterfaceTwo.ts
│	└──	ComponentWithInterfaces.vue

├──	ComponentWithPartials/
│	├──	partials/
│	│   ├── ComponentWithPartialsDefault.vue
│	│   ├── ComponentWithPartialsExternalLink.vue
│	│   └── ComponentWithPartialsInternalLink.vue
│	└──	ComponentWithPartials.vue

├──	ComponentWithEverything/
│	├──	abstracts/
│	│   ├── ExampleAbstractClassOne.ts
│	│   └── ExampleAbstractClassTwo.ts
│	├──	interfaces/
│	│   ├── ExampleInterfaceOne.ts
│	│   └── ExampleInterfaceTwo.ts
│	├──	partials/
│	│   ├── ComponentWithEverythingDefault.vue
│	│   ├── ComponentWithEverythingExternalLink.vue
│	│   └── ComponentWithEverythingInternalLink.vue
│ ├── ComponentWithEverything.vue
│ ├── index.ts
│ ├── types.ts
│	└──	style.scss

├──	index.ts
└──	types.ts

Structural Rules

As illustrated in the diagram above:

  • Each Component must live in a capital-case folder, named to exactly match the Component filename.

  • If an external SCSS file is necessary for that Component, it must live locally within the Component's folder, and be titled style.scss.

  • If additional TypeScript code is necessary for the Component's functionality (and cannot reasonably be included in the component definition itself), this code must be contained in an index.ts file that lives locally within that Component's folder.

  • Any TypeScript enums (enumerated types) that are used exclusively within this Component must be defined in a types.ts file that lives locally within that Component's folder.

  • If the Component requires any template partials, they must reside in a subfolder of the Component, labelled /partials, and each Component must be named as an extension of the primary component, with a descriptor appended.

  • If the Component requires any abstract classes, they must reside in a subfolder of the Component, labelled /abstracts.

  • If the Component requires any interfaces, they must reside in a subfolder of the Component, labelled /interfaces.

index.ts

The index.ts file located at the root of src/components re-exports all components in the Component Library. This allows developers to import multiple components into a component, using only one import statement with a multi-key object. This approach reduces code bloat and also creates a single source for tracking the appropriate paths to each component.

For example, including several components in another component changes from:

// Old Way
const importedComponents = {
    EjsAlert: use('ElentraJS/Components/Alert.vue'),
    EjsButton: use('ElentraJS/Components/Button.vue'),
    EjsHeading: use('ElentraJS/Components/Heading.vue'),
}

// New Way
import { 
    EjsAlert, 
    EjsButton, 
    EjsHeading 
} from '@/components';

types.ts

Also in the root of src/components, a types.ts file includes all of the enumerated types that may be shared across multiple components. For example, the context states for buttons (success, infoetc.) are also shared with alerts, so the keys for those contexts live in this file under a single enum:

export enum ContextualClass {
    Default = 'default',
    Primary = 'primary',
    Info = 'info',
    Success = 'success',
    Danger = 'danger',
    Disabled = 'disabled'
}

Last updated