DentalRay Web Components

This repository contains the shared custom elements.

Requirements

  • Node.js 18 or newer for the build step
  • PHP 8.1 or newer only if you want to use the local docs shell

Initial Setup

Install the PHP dependencies for this repository:

composer install

If npm is not available on the machine, install Node.js first. npm is included with Node.js.

Recommended with nvm:

nvm install 18
nvm use 18

Or install Node.js 18+ directly from the official installer, then verify:

node -v
npm -v

This project does not currently require npm install for the build step.

Build

npm run build

The build is dependency-free and writes output to dist/:

  • dist/web-components.js
  • one JS file per component, for example dist/button-component.js
  • one CSS file per component, for example dist/ButtonComponent.css
  • dist/tokens_v2.css

New components are discovered automatically during build when they follow this structure:

src/
  ComponentName/
    ComponentNameComponent.js
    ComponentNameComponent.css

Example:

src/
  Modal/
    ModalComponent.js
    ModalComponent.css

That will generate:

  • dist/modal-component.js
  • dist/ModalComponent.css

Main Project Integration

Use the bundled file in the main project instead of loading component files from src/.

1. Install the package in the main project

Add a VCS repository entry in the main project's composer.json.

Example:

{
  "repositories": [
    {
      "type": "vcs",
      "url": "git@bitbucket.org:dentalray/web-components.git"
    }
  ]
}

Then require the package:

composer require dentalray/web-components

If you want to install from a specific branch during development, use a branch constraint:

composer require dentalray/web-components:dev-main

Replace main with the branch name you actually want to consume.

2. Build this package

npm run build

3. Copy the built assets into the main project

Copy the dist/ files to a public asset directory in the main project.

If the main project installs this package through Composer, the source directory will usually be:

vendor/dentalray/web-components/dist/

Example:

main-project/
  public/
    assets/
      web-components/
        web-components.js
        tokens_v2.css
        button-component.js
        card-component.js

If the main project only uses the combined bundle, web-components.js is the required file.

Optional: automate the copy step with Composer Recommended

In the main project, add a custom Composer script so the assets are copied automatically after composer install and composer update.

Example composer.json in the main project:

{
  "scripts": {
    "sync-web-components": [
      "@php scripts/sync-web-components.php"
    ],
    "post-install-cmd": [
      "@sync-web-components"
    ],
    "post-update-cmd": [
      "@sync-web-components"
    ]
  }
}

Example scripts/sync-web-components.php in the main project:

<?php

$source = __DIR__ . '/../vendor/dentalray/web-components/dist';
$target = __DIR__ . '/../public/assets/web-components';

if (!is_dir($source)) {
    fwrite(STDERR, "Missing source directory: {$source}\n");
    exit(1);
}

if (!is_dir($target) && !mkdir($target, 0777, true) && !is_dir($target)) {
    fwrite(STDERR, "Unable to create target directory: {$target}\n");
    exit(1);
}

$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($source, FilesystemIterator::SKIP_DOTS),
    RecursiveIteratorIterator::SELF_FIRST
);

foreach ($iterator as $item) {
    $destination = $target . DIRECTORY_SEPARATOR . $iterator->getSubPathName();

    if ($item->isDir()) {
        if (!is_dir($destination)) {
            mkdir($destination, 0777, true);
        }
        continue;
    }

    copy($item->getPathname(), $destination);
}

echo "Web components copied to {$target}\n";

That gives the main project a manual command. Run this in the main project root:

composer sync-web-components

This keeps the copied assets up to date after Composer install and update operations.

.gitignore the web component files in the main project to prevent bloating:

public/assets/web-components/

4. Load the bundle on pages that use the components

<script defer src="/assets/web-components/web-components.js"></script>

That bundle:

  • registers the components
  • injects the shared design tokens automatically
  • embeds component CSS, so it does not depend on /src/... paths

5. Use the custom elements in markup

Example:

<dr-button variant="btn-primary">Save</dr-button>

6. Rebuild when this package changes

Whenever components, tokens, or component CSS change in this repository:

  1. run npm run build
  2. push the changes
  3. run a composer update in the main project
  4. replace the copied dist/ assets in the main project

Important Notes

  • Do not load /src/Button/ButtonComponent.js or other /src/... files from the main project.
  • The local docs shell now loads the built bundle from /dist/web-components.js.
  • The production-safe integration path for the main project is dist/web-components.js.

Development Preview

The local docs/demo shell is still served by index.php and the files under templates/.

If you want to preview components locally with PHP:

npm run build
php -S localhost:8000

Then open http://localhost:8000/index.php.