{"_id":"@dloizides/ui-email-center","name":"@dloizides/ui-email-center","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.1":{"name":"@dloizides/ui-email-center","version":"0.1.1","description":"Shared, brand-agnostic React Native (RN-web) 'Email Center' surface for the dloizides.com portfolio: a per-product registry of every transactional email a product sends, organized by an extensible business taxonomy, with per-tenant/per-event copy customiz","keywords":["react","react-native","react-native-web","ui","email","email-templates","transactional-email","preview","dloizides"],"author":{"name":"dloizides"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/openmindednewby/ui-email-center.git"},"homepage":"https://github.com/openmindednewby/ui-email-center#readme","bugs":{"url":"https://github.com/openmindednewby/ui-email-center/issues"},"main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"react-native":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"browser":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"default":{"types":"./dist/index.d.ts","default":"./dist/index.js"}}},"sideEffects":false,"engines":{"node":">=18.0.0"},"scripts":{"build":"rimraf dist && tsup","build:watch":"tsup --watch","test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage","lint":"eslint src --ext .ts,.tsx","lint:fix":"eslint src --ext .ts,.tsx --fix","typecheck":"tsc --noEmit","clean":"rimraf dist","security:audit":"npm audit --audit-level=high","prepublishOnly":"npm run clean && npm run build && npm run test"},"peerDependencies":{"@dloizides/ui-buttons":">=1.4.0","@dloizides/ui-feedback":">=1.1.0","@dloizides/ui-forms":">=1.8.0","react":">=18.0.0","react-dom":">=18.0.0","react-native":">=0.74.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"devDependencies":{"@dloizides/ui-buttons":"^1.8.0","@dloizides/ui-feedback":"^1.8.0","@dloizides/ui-forms":"^1.12.0","@testing-library/dom":"^10.4.0","@testing-library/jest-dom":"^6.6.3","@testing-library/react":"^16.1.0","@types/jest":"^29.5.0","@types/node":"^20.19.32","@types/react":"^19.0.0","@types/react-dom":"^19.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@typescript-eslint/parser":"^7.0.0","eslint":"^8.57.0","eslint-plugin-react":"^7.34.0","eslint-plugin-react-hooks":"^4.6.0","jest":"^29.7.0","jest-environment-jsdom":"^29.7.0","react":"^19.2.4","react-dom":"^19.2.4","react-native":"0.81.5","react-native-web":"^0.21.0","rimraf":"^5.0.0","ts-jest":"^29.1.0","tsup":"^8.0.0","typescript":"^5.4.0"},"_id":"@dloizides/ui-email-center@0.1.1","gitHead":"3a01fac77bb5755ed89030b135a43a1771cec3e6","_nodeVersion":"22.18.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-zg3aDZetW+CE1uWErF3qXdM4yCWtnnemuhl1IqzElUaVc/iBLWjQEh16Y1MLXnAuoSxqgRBZN5iPXn29D40ISg==","shasum":"34962b594967dfd10322d2ce001fd9ed2cedb062","tarball":"https://registry.npmjs.org/@dloizides/ui-email-center/-/ui-email-center-0.1.1.tgz","fileCount":11,"unpackedSize":200381,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCAK/68ZWwnK/k3aHHqsA/YMj28gQeXGfpdRTUSoY1UyQIhANsHYmjG3HBlYoz1/ssKXw3NLFrLYsHOGSCyo2ZKzeq7"}]},"_npmUser":{"name":"dloizides","email":"loizidesdemetris@gmail.com"},"directories":{},"maintainers":[{"name":"dloizides","email":"loizidesdemetris@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ui-email-center_0.1.1_1785581489805_0.4633469635316363"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-01T10:51:29.647Z","0.1.1":"2026-08-01T10:51:29.977Z","modified":"2026-08-01T10:51:30.195Z"},"maintainers":[{"name":"dloizides","email":"loizidesdemetris@gmail.com"}],"description":"Shared, brand-agnostic React Native (RN-web) 'Email Center' surface for the dloizides.com portfolio: a per-product registry of every transactional email a product sends, organized by an extensible business taxonomy, with per-tenant/per-event copy customiz","homepage":"https://github.com/openmindednewby/ui-email-center#readme","keywords":["react","react-native","react-native-web","ui","email","email-templates","transactional-email","preview","dloizides"],"repository":{"type":"git","url":"git+https://github.com/openmindednewby/ui-email-center.git"},"author":{"name":"dloizides"},"bugs":{"url":"https://github.com/openmindednewby/ui-email-center/issues"},"license":"MIT","readme":"# @dloizides/ui-email-center\n\nShared, brand-agnostic React Native (RN-web) **Email Center** for the dloizides.com portfolio: a\nper-product registry of every transactional email a product sends, organized by an **extensible\nbusiness taxonomy**, with **per-tenant/per-event copy customization** and **dynamic-field\n(`{{token}}`) preview**.\n\nBuilt on `@dloizides/ui-feedback` (theme + `t`), `@dloizides/ui-forms` (`FormField`, `FormSwitch`)\nand `@dloizides/ui-buttons` (`Button`). No raw colour literals; every interactive element carries\n`testID` + `accessibilityLabel` + `accessibilityHint`; every string is an injected i18n key.\n\n## The idea\n\nEach product **registers** its own `EmailCategory[]` (the taxonomy) and `EmailKind[]` (the emails it\nsends). The package owns the shared shell: a grouped list → a token-substituted preview → a copy\neditor. Persistence and delivery-status are **ports** the app injects — the package never talks to a\nbackend.\n\n```tsx\nimport { EmailCenter } from '@dloizides/ui-email-center';\n\n<EmailCenter\n  categories={PRODUCT_EMAIL_CATEGORIES}\n  kinds={PRODUCT_EMAIL_KINDS}\n  overrides={savedOverrides}\n  onSaveOverride={(o) => api.put('/email-center/overrides', o)}\n  sendStatus={sendStatusByKindId}\n  testID=\"organizer-emails\"\n/>\n```\n\n## Model\n\n| Type | Purpose |\n|---|---|\n| `EmailCategory` | a taxonomy bucket (`transactional` / `lifecycle` / `approval` / …), with `order` |\n| `EmailField` | a dynamic `{{token}}` a template exposes, with a `sample` for the preview |\n| `EmailTemplateContent` | the editable copy: `subject`, `heading`, `bodyBlocks[]`, `ctaLabel?`, `ctaUrlToken?`, `footerNote?` |\n| `EmailKind` | one email; carries `defaultContent` (mirrors backend `Email.Templating`), `fields`, and configurable `senderIdentityI18nKey` / `replyChannelI18nKey` |\n| `EmailOverride` | a per-tenant/per-event partial override + `autoSend` toggle |\n\n## Pure logic (framework-free — also usable in a backend preview endpoint)\n\n- `groupKindsByCategory(categories, kinds)` — the ordered, empty-omitted taxonomy view.\n- `mergeContent(base, override)` — layer a partial override over the default.\n- `substituteTokens(text, values)` — resolve `{{token}}` (unknown tokens stay visible).\n- `renderPreview(kind, override?, values?)` — the fully-resolved preview model.\n- `diffOverride` / `buildOverride` / `isDraftDirty` — minimal-override + dirty tracking for the editor.\n- `createEmailRegistry(categories, kinds)` — a read model (`groups()`, `kind(id)`, `orphanKindIds()`).\n\n## Adoption\n\nSee [`ADOPTION.md`](ADOPTION.md) for the per-app checklist (register kinds, mount the surface, add the\n`EMAIL_CENTER_I18N` keys, wire the two ports). `src/examples/kefi.registry.ts` is a complete, typed,\ntested first-adopter example.\n\n## Development\n\n```bash\nnpm install\nnpm run build     # tsup → dist (cjs + esm + d.ts)\nnpm test          # jest — logic + hook unit tests\nnpm run lint\nnpm run typecheck\n```\n","readmeFilename":"README.md","_rev":"1-058519f0807843dc285910d7edb63784"}