@keystone-sites/widgets
v1.0.1
Published
Keystone Sites Widgets - shippable product surfaces (forms, chat widget, member portal) for customer websites
Downloads
142
Keywords
Readme
@keystone-sites/widgets
Shippable product surfaces for Keystone customer websites: dynamic forms, the chat widget, and the member portal. These are long-lived product features that ship on every site — legacy themed sites and new generated sites alike.
- Forms —
DynamicFormFieldsrenders a form definition fetched from the Keystone API;FormDefinitionsProvider/useFormDefinitionsdistribute prefetched definitions through the tree. Pairs with the@keystone-sites/coreform route handler. - Chat —
ChatWidgetwith realtime replies over Action Cable. Pairs with the@keystone-sites/corechat route handler. - Portal —
PortalPageand its sub-components (auth, booking, messaging). Pairs with the@keystone-sites/coreconsumer-auth route handler.
The handful of UI primitives these widgets need (modal, inputs, button, avatar, cx, phone helpers, countries) are vendored into this package as internal, unexported modules — this package has no dependency on the deprecated keystone-legacy-templates theme system by design.
Package exports
| Import path | Contents |
|---|---|
| @keystone-sites/widgets | ChatWidget, DynamicFormFields, FormDefinitionsProvider, useFormDefinitions |
| @keystone-sites/widgets/components/ChatWidget | ChatWidget |
| @keystone-sites/widgets/components/DynamicFormFields | DynamicFormFields |
| @keystone-sites/widgets/next/contexts/form-definitions | FormDefinitionsProvider, useFormDefinitions |
| @keystone-sites/widgets/portal | PortalPage, LoginForm, LogoutButton, LoginModalController |
| @keystone-sites/widgets/portal/LoginForm | LoginForm |
| @keystone-sites/widgets/portal/LoginModalController | LoginModalController |
| @keystone-sites/widgets/theme.css | Design-token theme + Tailwind source scan (see Styling) |
Styling (required)
These widgets are built from vendored Untitled UI primitives and ship no
compiled CSS. Their Tailwind v4 classes only exist if the host app both
scans this package's source for class names and defines the Untitled UI
token layer those classes reference. theme.css does both — import it once in
the app's globals.css, after @import "tailwindcss":
@import "tailwindcss";
@import "@keystone-sites/widgets/theme.css"; /* token layer + `@source "../src"` scan */It ships a neutral default palette. Re-brand the widgets by overriding the
private --kw-* primitives (and the --radius-* / --font-* widget tokens) in
your own @theme, imported after this file so it wins:
@theme {
--kw-brand-600: #8c6440; --kw-brand-700: #6d4e32; /* brand ramp 25..950 */
--kw-neutral-900: #1e1e1e; /* neutral ramp 25..950 */
--radius-input: 0.25rem; --font-body: var(--font-sans);
}The semantic value layer (--color-text-*, --color-bg-*, …) and Tailwind v4
property-namespace layer (--text-color-*, --background-color-*, …) resolve
through those primitives automatically, so text-primary (ink) and bg-primary
(surface) stay distinct. Skipping this import leaves every form field, the
portal, and the chat widget unstyled — brand surfaces collapse to white and
their white text becomes invisible.
Source directory structure
src/
├── design_system/
│ ├── components/ # ChatWidget, DynamicFormFields
│ ├── chat/ # Realtime reply orchestrator (Action Cable)
│ ├── portal/ # Member portal page + sub-components
│ ├── elements/ # Vendored UI primitives (internal, unexported)
│ └── logo/ # Vendored Keystone brand marks (internal, unexported)
├── lib/hooks/ # Vendored hooks (internal)
├── next/contexts/ # FormDefinitionsProvider
├── types/ # Ambient types (@rails/actioncable)
└── utils/ # Vendored utils (cx, countries, phone-helpers; internal)Publishing workflow
Publish to the public npm registry in dependency order (wait for each package to propagate before publishing dependents):
# 1. @keystone-sites/core (no internal Keystone deps)
npm run test && npm publish --access public
# 2. @keystone-sites/services (depends on @keystone-sites/core)
npm run test && npm publish --access public
# 3. @keystone-sites/widgets (depends on @keystone-sites/core + @keystone-sites/services)
npm run test && npm publish --access publicprepublishOnly runs npm run build automatically before each publish.
For local development against an unpublished build, use yalc:
# In @keystone-sites/widgets — build and publish to local yalc store
npm run build && yalc publish
# In the customer site — link to the local build
yalc add @keystone-sites/widgets
# or update an existing link
yalc update @keystone-sites/widgetsTo restore the published npm version:
yalc remove @keystone-sites/widgets
npm installDocs
docs/forms.md— dynamic formsdocs/member-portal.md— member portal
