@eekaam/ui
v1.1.0
Published
Eekaam's UI kit for apps: web components that look like the admin, served from the Eekaam CDN.
Readme
@eekaam/ui
The Eekaam UI kit: web components that look like the merchant admin, for apps that run inside it. Served from the Eekaam CDN so a design change reaches every app without the app redeploying.
Use it
<script type="module" src="https://themes-cdn.eekaam.com/ui/v1/ui.js"></script>
<e-page heading="Payments">
<e-button slot="primary-action">Save</e-button>
<e-card heading="Provider">
<e-text-field name="name" label="Display name" required></e-text-field>
</e-card>
</e-page>React: @eekaam/ui-react gives typed components over the same elements. Keep
the script tag; the wrappers contain no element code.
window.eekaam offers toast, navigate, setTitle, sessionToken,
isEmbedded, onSchemeChange, setAppLocation and openAdmin for apps
without a bundler.
App navigation (1.1)
List the app's pages in the admin's navigation, under the app:
<e-app-nav>
<a href="/" rel="home">Home</a>
<a href="/settings">Settings</a>
</e-app-nav>Paths are relative to the app's embedded URL. The home link (rel="home",
else the first href="/") is not listed — the app's own entry leads there.
The links stay the app's own elements, so a router's <a> keeps working, and
the list is sent again whenever they change. Inside the admin the element
draws nothing; outside it, or in an admin that cannot list pages, it draws the
links as a row of tabs (mark the current one with aria-current="page").
Clicking a listed page reloads the frame at that path. After a client-side navigation, report where the app is so the admin's address bar follows:
setAppLocation(location.pathname); // query and fragment are left outReact: <AppNav> with the same children, and setAppLocation from
@eekaam/ui-react (call it from your router's location effect).
Opening admin pages (1.1)
openAdmin("edit:product", "gid://eekaam/Product/123"); // or a plain id
openAdmin("create:order");Intents: edit: / create: for product, order and collection, and
edit:customer. The admin moves the merchant through its unsaved-changes
guard.
Modal and save bar inside the admin
Inside the admin, some overlays are drawn by the admin itself, over the whole window, instead of inside the app's frame.
<e-modal>is drawn by the admin when its body is plain text (no elements outside theprimary-action/secondary-actionslots, which hold<e-button>s, at most two secondary). The buttons become the admin's buttons; pressing one clicks the<e-button>, soclickhandlers work unchanged. Escape or ✕ in the admin firese-request-close(reason"escape"); prevent it to keep the modal open. Rich content,loading,size="fullscreen", thein-frameattribute, or an admin that does not answer draw in the frame as before.<e-save-bar>puts the admin into its "unsaved changes" state, which also stops the merchant leaving the page. Outside the admin it is a sticky bar at the top of its container.<e-save-bar watch-form="settings" discard-confirmation></e-save-bar> <form id="settings">…</form>Editing the form opens the bar. Save fires
e-saveand, unless prevented, submits the form and setssaving; end the save withopen = falsewhen it worked orsaving = falsewhen it did not — the admin shows its spinner only whilesavingis set. Discard firese-discardand, unless prevented, resets the form and closes the bar. Withoutwatch-form, setopenyourself and handle both events.
Versions
/ui/v1/ui.js— latest 1.x. Apps load this./ui/<x.y.z>/ui.js— one exact build, never changes.
Inside v1, props, attributes, events, slots and parts only ever get added.
Anything that would break an app waits for /ui/v2/.
Work on it
pnpm --filter @eekaam/ui dev # index.html: every component
pnpm --filter @eekaam/ui test # headless Chromium
pnpm --filter @eekaam/ui build # dist/ui.js + dist/types
EEKAAM_UI_BUCKET=… EEKAAM_UI_DISTRIBUTION_ID=… pnpm --filter @eekaam/ui release [--dry-run]Colours, spacing and type come from @eekaam/tokens, which the dashboard also
reads. Change a token there, not here.
