{"_id":"@abhishek14gupta/recipe-ui-components","name":"@abhishek14gupta/recipe-ui-components","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@abhishek14gupta/recipe-ui-components","version":"0.1.0","description":"Reusable recipe UI web components (Stencil).","private":false,"license":"MIT","main":"dist/index.cjs.js","module":"dist/index.js","types":"dist/types/index.d.ts","collection":"dist/collection/collection-manifest.json","collection:main":"dist/collection/index.js","unpkg":"dist/recipe-ui/recipe-ui.esm.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/recipe-ui/recipe-ui.esm.js","require":"./dist/recipe-ui/recipe-ui.cjs.js"},"./components":{"types":"./dist/components/index.d.ts","import":"./dist/components/index.js"},"./loader":{"types":"./loader/index.d.ts","import":"./loader/index.js","require":"./loader/index.cjs"}},"scripts":{"build":"stencil build","start":"stencil build --dev --watch --serve","test":"stencil-test --prod","test:watch":"stencil-test --prod --watch","generate":"stencil generate","prepublishOnly":"npm run build"},"devDependencies":{"@stencil/core":"^4.27.1 || ^5.0.0-0","@stencil/vitest":"^1.8.3","@types/node":"^22.13.5","@vitest/browser-playwright":"^4.0.0","playwright":"^1.52.0","vitest":"^4.0.0"},"gitHead":"f32c46037d6b4d950ada23049e46eeca8ac40906","_id":"@abhishek14gupta/recipe-ui-components@0.1.0","_nodeVersion":"26.7.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-20i+Q6l9NbXaNWYk8mWG2vNz5PrIrTcbsSdbKT1IjAqQ2LuRmsKC7/3/X/0q6J4EmxGWsV75UJTOJ7OPxzwq5Q==","shasum":"b8185180652ef8647d1a42d4212912d1738da170","tarball":"https://registry.npmjs.org/@abhishek14gupta/recipe-ui-components/-/recipe-ui-components-0.1.0.tgz","fileCount":69,"unpackedSize":328612,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD4ld8tP9ZCItNU2kPwKlJnGoF8tyYs/NXBMPjQCZtSJgIgG91X0tCbfIX2YQybY+A7VxeuL+i9Zjm9nqoeTAha9T4="}]},"_npmUser":{"name":"abhishek14gupta","email":"gupta14082000@gmail.com"},"directories":{},"maintainers":[{"name":"abhishek14gupta","email":"gupta14082000@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/recipe-ui-components_0.1.0_1788181095243_0.7566161750647373"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T12:58:15.040Z","0.1.0":"2026-08-31T12:58:15.376Z","modified":"2026-08-31T12:58:15.694Z"},"maintainers":[{"name":"abhishek14gupta","email":"gupta14082000@gmail.com"}],"description":"Reusable recipe UI web components (Stencil).","license":"MIT","readme":"# `@abhishek14gupta/recipe-ui-components`\r\n\r\nFramework-agnostic recipe UI built with [Stencil](https://stenciljs.com/). Components render as real Custom Elements with Shadow DOM.\r\n\r\nVersion **0.1.0**. Until 1.0.0, minor bumps may include breaking changes; patch bumps are fixes only. After 1.0.0 we follow standard semver.\r\n\r\nGitHub: https://github.com/abhishek14gupta/recipe-finder\r\n\r\n## Develop\r\n\r\nFrom the monorepo root:\r\n\r\n```sh\r\nnpm install\r\nnpm run dev:ui\r\n```\r\n\r\nPreview: http://localhost:3333\r\n\r\n```sh\r\nnpm run build:ui\r\nnpm test --workspace=packages/recipe-ui\r\n```\r\n\r\nTests use Stencil’s current Vitest runner (`@stencil/vitest`), not the older `@stencil/core/testing` Jest helper.\r\n\r\n## Consume (after install)\r\n\r\nThe SvelteKit app in this monorepo currently uses:\r\n\r\n`\"@abhishek14gupta/recipe-ui-components\": \"file:../../packages/recipe-ui\"`\r\n\r\nAfter you publish to npm, replace that with the registry version (see the root README).\r\n\r\n```js\r\nimport { defineCustomElements } from '@abhishek14gupta/recipe-ui-components/components';\r\n\r\ndefineCustomElements();\r\n```\r\n\r\nLazy loader (alternative):\r\n\r\n```js\r\nimport { defineCustomElements } from '@abhishek14gupta/recipe-ui-components/loader';\r\n\r\ndefineCustomElements();\r\n```\r\n\r\n**Primitives** (`string`, `boolean`, `number`) can be HTML attributes. **Objects and arrays** (`tags`, `assignedRecipe`) must be set as element **properties**.\r\n\r\n## Theming\r\n\r\nSet CSS custom properties on `:root` or a parent of the element (they pierce into shadow via inheritance):\r\n\r\n| Property | Used by | Default idea |\r\n| --- | --- | --- |\r\n| `--recipe-card-radius` | `recipe-card` | `12px` |\r\n| `--recipe-card-shadow` | `recipe-card` | soft drop shadow |\r\n| `--recipe-card-bg` / `--recipe-card-fg` | `recipe-card` | white / slate |\r\n| `--recipe-card-accent` | `recipe-card` favorite | rust |\r\n| `--recipe-badge-radius` | `recipe-badge` | pill |\r\n| `--recipe-badge-bg` / `--recipe-badge-fg` | `recipe-badge` | muted chip |\r\n| `--meal-plan-day-radius` / `--meal-plan-day-border` | `meal-plan-day` | 12px / slate |\r\n| `--recipe-search-radius` / `--recipe-search-accent` | `recipe-search-bar` | 10px / rust |\r\n\r\n## Components\r\n\r\n### `<recipe-card>`\r\n\r\nSummary card with favorite control. Inject extra buttons through the actions slot so the library stays app-agnostic.\r\n\r\n**Props**\r\n\r\n| Prop | Type | Notes |\r\n| --- | --- | --- |\r\n| `recipeId` | `string` | Required. Sent as `detail.id` on favorite toggle. Attribute: `recipe-id`. |\r\n| `recipeTitle` | `string` | Heading. Attribute: `recipe-title`. (`title` is reserved on HTMLElement.) |\r\n| `image` | `string` | Optional URL. |\r\n| `category` | `string` | Optional. |\r\n| `tags` | `string[]` | **Property only.** |\r\n| `isFavorite` | `boolean` | Attribute: `is-favorite`. |\r\n\r\n**Events**\r\n\r\n| Event | Detail |\r\n| --- | --- |\r\n| `favoriteToggle` | `{ id: string }` |\r\n\r\n**Slots**\r\n\r\n| Slot | Purpose |\r\n| --- | --- |\r\n| `actions` | Host-provided actions (e.g. “Add to plan”). |\r\n\r\n```html\r\n<recipe-card recipe-id=\"52772\" recipe-title=\"Teriyaki\" category=\"Chicken\">\r\n  <button slot=\"actions\" type=\"button\">Add to plan</button>\r\n</recipe-card>\r\n<script>\r\n  const card = document.querySelector('recipe-card');\r\n  card.tags = ['soy'];\r\n  card.addEventListener('favoriteToggle', (e) => console.log(e.detail.id));\r\n</script>\r\n```\r\n\r\n### `<recipe-badge>`\r\n\r\nPresentational source/difficulty chip. No app state.\r\n\r\n**Props**\r\n\r\n| Prop | Type | Notes |\r\n| --- | --- | --- |\r\n| `label` | `string` | Required text. |\r\n| `variant` | `'api' \\| 'user' \\| 'difficulty' \\| 'default'` | Reflected as attribute. |\r\n\r\n**Events / slots:** none.\r\n\r\n### `<meal-plan-day>`\r\n\r\nOne day in a weekly planner.\r\n\r\n**Props**\r\n\r\n| Prop | Type | Notes |\r\n| --- | --- | --- |\r\n| `day` | `string` | e.g. `Mon`. |\r\n| `assignedRecipe` | `{ id, title, image?, source? } \\| null` | **Property only.** |\r\n\r\n**Events**\r\n\r\n| Event | Detail |\r\n| --- | --- |\r\n| `removeMeal` | `{ day: string }` |\r\n| `changeMeal` | `{ day: string }` |\r\n\r\n**Slots**\r\n\r\n| Slot | Purpose |\r\n| --- | --- |\r\n| default | Empty-state content when no recipe is assigned. |\r\n\r\n### `<recipe-search-bar>`\r\n\r\nControlled search field. Typing emits `searchChange` after **300ms**. Submitting the form (Enter) emits `filterChange` immediately.\r\n\r\n**Props**\r\n\r\n| Prop | Type | Notes |\r\n| --- | --- | --- |\r\n| `value` | `string` | Controlled value. |\r\n| `label` | `string` | Accessible name (visually hidden). |\r\n| `placeholder` | `string` | Input placeholder. |\r\n\r\n**Events**\r\n\r\n| Event | Detail |\r\n| --- | --- |\r\n| `searchChange` | `{ value: string }` (debounced 300ms) |\r\n| `filterChange` | `{ value: string }` (submit) |\r\n\r\n**Slots**\r\n\r\n| Slot | Purpose |\r\n| --- | --- |\r\n| default | Extra filter controls (chips, selects). |\r\n\r\n## Publish\r\n\r\n`prepublishOnly` runs `stencil build`. Published files: `dist/`, `loader/`, `README.md`.\r\n\r\n```sh\r\n# TODO (you)\r\nnpm login\r\ncd packages/recipe-ui\r\nnpm publish --access public\r\n```\r\n","readmeFilename":"README.md","_rev":"1-0ff99febff107079fac2b5a0011eab0a"}