Make bundled packages and utils used in code components available outside Canvas
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3560419. -->
Reported by: [wotnak](https://www.drupal.org/user/3558113)
Related to !427 !383
>>>
<h3 id="overview">Overview</h3>
<p>Drupal Canvas provides several utilities, a FormattedText component, and autoconfigured @drupal-api-client/json-api-client and next-image-standalone packages for use in code components. Currently these are not really possible to be used outside of Canvas in a React codebase used with @drupal-canvas/cli to develop Canvas components.</p>
<h3 id="proposed-resolution">Proposed resolution</h3>
<p>Extract those elements to a separate package that can be used both in Canvas and outside it in a React codebase.</p>
<ol>
<li>Add a new package under <code>packages/drupal-canva</code> which will be publish as <code>drupal-canvas</code>.</li>
<li>The following elements should be moved from <a href="https://git.drupalcode.org/project/canvas/-/tree/3677c3fdc8ea143d3de765071e2a7288dd35dd7f/ui/lib/astro-hydration/src/lib">ui/lib/astro-hydration/src/lib</a> to the new package and, if needed, adapted to work also outside Canvas:
<ul>
<li><code>@/lib/drupal-utils</code></li>
<li><code>@/lib/FormattedText</code></li>
<li><code>@/lib/jsonapi-utils</code></li>
<li><code>@/lib/utils</code></li>
<li><code>@drupal-api-client/json-api-client</code><br>
The automatic configuration of the client will need to be adapted to also work outside Canvas in a React codebase. The client should know how to connect to a Drupal site so lists can be built locally. The base URL can be read from the environment variable that would be set up for the CLI tool. The tricky part is exposing the jsonapi.base_path service parameter. See how it was done in a browser context <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3536124" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3536124</a></span>.
</li>
<li><code>next-image-standalone</code><br>
The image component in context outside Canvas should provide a loader that just returns the same image URL/path without any optimization. Trying to optimize example images from component.yml files might need <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3559717" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3559717</a></span> to work first, though that is for SDCs, but maybe it’s a similar challenge under the hood.
</li>
</ul>
<p> The package should provide named exports from the main file to allow for import autocompletion and provide a single package to import from (e.g. <code>import { Image, JsonApiClient } from 'drupal-canvas'</code>) but also still provide separate exports compatible with the current ones to allow for maintaining backward-compatible import map entries (e.g. <code>import Image from 'next-image-standalone'</code> or <code>import { JsonApiClient } from '@drupal-api-client/json-api-client';</code> that can be mapped using the import map to <code>import Image from 'drupal-canvas/next-image-standalone'</code> or <code>import { JsonApiClient } from 'drupal-canvas/json-api-client'</code>).
</p></li>
<li>Add the new package as a dependency of <a href="https://git.drupalcode.org/project/canvas/-/tree/1.x/ui"><code>@drupal-canvas/ui</code></a> and update the import map (<a href="https://git.drupalcode.org/project/canvas/-/blob/3677c3fdc8ea143d3de765071e2a7288dd35dd7f/src/Plugin/Canvas/ComponentSource/JsComponent.php#L166">1</a>, <a href="https://git.drupalcode.org/project/canvas/-/blob/3677c3fdc8ea143d3de765071e2a7288dd35dd7f/ui/src/features/code-editor/Preview.tsx#L77">2</a>) to point existing entries to the new package and add a new entry for the package itself.</li>
<li>Update <a href="https://git.drupalcode.org/project/canvas/-/tree/3677c3fdc8ea143d3de765071e2a7288dd35dd7f/docs/user/src/content/docs#L166">user documentation</a> on packages, data fetching, and responsive images to include information about the new package and use it in code examples.</li>
<li>Update <code>component-imports</code> rule in the <a href="https://www.drupal.org/project/canvas/issues/3559127"><code>@drupal-canvas/eslint-config</code></a> to:
<ul>
<li>allow imports from the new package,</li>
<li>and to warn about existing import specifiers being deprecated in favor of the new package.</li>
</ul>
</li>
</ol>
issue