Skip to content

Contributing ​

Branching ​

The repository for @studiometa/ui follows a trunk-based workflow with main as the single principal branch:

  • feature/... for new features
  • fix/... for bug fixes

Every merge should be first approved by opening a pull-request against the main branch.

Local development ​

Clone the project and install the required dependencies. The back-end can be run with ddev which is preconfigured.

bash
git clone https://github.com:studiometa/ui.git
cd ui/

# Install NPM dependencies
npm install
ddev start

# Launch the dev environment
npm run docs:dev

You will then be able to open the documentation development URL localhost:5173/-/ in your browser.

The TypeScript files from the @studiometa/ui packages can be imported in the playground by using a ESM import statement:

js
import { Figure } from '@studiometa/ui';

While in dev mode, the source TypeScript files will be automatically rebuild on change and made available to the playground at localhost:5173/-/play/index.html.

You can also open the repository in GitPod and start the dev environment there.

Remote development with Gitpod ​

The repository is also configured to easily run in Gitpod. Just click on the following button to get started:

Open in Gitpod

Adding a component ​

A component can either be a single TypeScript file, a single Twig template or for more complex features, a combination of both.

💡 Pro tip

Take inspiration from existing components for new implementations.

TypeScript ​

The default template for a TypeScript component is as follow:

ts
import { Base } from '@studiometa/js-toolkit';
import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';

export interface NameProps extends BaseProps {}

/**
 * Name class.
 */
export default class Name extends Base<NameProps> {
  static config: BaseConfig = {
    name: 'Name',
  };
}

Once your component is ready, export its public content from the family index.ts file and from packages/ui/index.ts. Add or update its entry in the documentation reference catalog so its symbols, package, surfaces and lifecycle status remain discoverable:

diff
 export * from './Modal/index.js';
+export * from './MyComponent/index.js';
 export * from './Panel/index.js';

Twig ​

All Twig templates should at least expose an attr variable that can be used to configure the attributes of the HTML root element of the template. To facilitate this pattern, we use functions added by our studiometa/twig-toolkit.

twig
{% set default_attributes = { class: 'block' } %}
{% set required_attributes = { data_component: 'MyComponent' } %}

{% set attributes = merge_html_attributes(
  attr ?? null,
  default_attributes,
  required_attributes,
) %}

<div {{ html_attributes(attribute) }}>
  ...
</div>

Changelog ​

Do not edit the CHANGELOG.md file. Each pull-request adds a fragment in .changelog/<slug>.md, where the slug is the branch name without its prefix (feature/my-component → my-component.md). A fragment only contains Keep a Changelog ### sections followed by their entries:

md
### Added

- **MyComponent:** add the `MyComponent` component

### Fixed

- **Fetch:** fix the history update after a form submit

Do not write the pull-request number: the release adds it. A pull-request that changes a published package needs a fragment, unless it has the no-changelog label (tests, docs, refactors, tooling). See weareikko/changelog for the format.

Publishing a new version ​

Each merge into main releases a new 1.x version with the release workflow (.github/workflows/publish.yml). The workflow runs the tests, then computes the version from the .changelog/ fragments: a breaking entry (⚠️) gives a major version, an Added entry a minor version and other entries a patch version. It folds the fragments into CHANGELOG.md, updates the version number of all packages and of composer.json, commits and tags the release, creates a release on GitHub and publishes the @studiometa/ui packages to NPM with the latest tag. The Packagist package will be updated with the latest tag as well. A merge without a fragment releases nothing.

To force a bump, for example a major version without a breaking entry, run the workflow in the Actions tab or with the GitHub CLI:

sh
gh workflow run publish.yml --ref main -f version=major

To release prereleases, add a .changelog/prerelease file with one identifier, such as beta. While it exists, each merge releases the next prerelease (1.12.0-beta.0, then 1.12.0-beta.1). A prerelease is a GitHub prerelease and goes to the next-1.x tag on NPM: it does not change the latest tag on NPM or the latest release on GitHub. The merge of the pull-request that deletes the file releases the stable version, also without a new fragment. See Prereleases.

NPM publishes the packages with trusted publishing, so the workflow uses no NPM token. When the publication fails, use "Re-run failed jobs" on the workflow run: the packages that NPM already has are skipped and the others are published.

The 2.x branch releases the next major version on each merge into 2.x, on the NPM next tag. Merge main into 2.x after the release workflow of main has finished: the fragments of main that are not released yet would otherwise also go into the next 2.x release.