@ssingh465/recipe-ui 0.2.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/day-picker.js +1 -1
- package/dist/components/empty-state.js +1 -1
- package/dist/components/filter-chip.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/planner-day.js +1 -1
- package/dist/components/recipe-card.js +1 -1
- package/dist/components/recipe-grid.js +1 -1
- package/dist/components/skeleton-card.js +1 -1
- package/dist/components/tile-hue.js +1 -0
- package/dist/types/components/planner-day/planner-day.d.ts +1 -0
- package/dist/types/components.d.ts +0 -62
- package/package.json +1 -1
- package/readme.md +14 -6
- package/dist/components/spike-panel.d.ts +0 -11
- package/dist/components/spike-panel.js +0 -1
- package/dist/types/components/spike-panel/spike-panel.cmp.test.d.ts +0 -1
- package/dist/types/components/spike-panel/spike-panel.d.ts +0 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxyCustomElement as e,HTMLElement as s,createEvent as i,h as t,Host as r,transformTag as a}from"@stencil/core/internal/client";import{C as n,a as o}from"./icons.js";const c=e(class extends s{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.planassign=i(this,"planassign",7),this.pickerclose=i(this,"pickerclose",7)}recipeId;days;label;planassign;pickerclose;isOpen=!1;activeIndex=0;async open(){this.openPanel()}triggerEl;panelEl;dayEls=[];reposition=()=>this.positionPanel();handleOutsideClick=e=>{const s=e.composedPath();this.triggerEl&&this.panelEl&&(s.includes(this.triggerEl)||s.includes(this.panelEl)||this.closePanel(!1))};disconnectedCallback(){window.removeEventListener("resize",this.reposition),window.removeEventListener("scroll",this.reposition,!0),document.removeEventListener("pointerdown",this.handleOutsideClick,!0)}positionPanel(){if(!this.triggerEl||!this.panelEl)return;const e=this.triggerEl.getBoundingClientRect(),s=window.innerHeight-e.bottom<320?e.top-(this.panelEl.offsetHeight||324)-4:e.bottom+4;this.panelEl.style.left=e.left+"px",this.panelEl.style.top=s+"px"}openPanel=()=>{this.isOpen=!0,this.activeIndex=0,requestAnimationFrame((()=>{this.panelEl?.showPopover?.(),this.positionPanel(),this.dayEls[0]?.focus(),window.addEventListener("resize",this.reposition),window.addEventListener("scroll",this.reposition,!0),document.addEventListener("pointerdown",this.handleOutsideClick,!0)}))};closePanel=e=>{this.isOpen&&(this.isOpen=!1,this.panelEl?.hidePopover?.(),window.removeEventListener("resize",this.reposition),window.removeEventListener("scroll",this.reposition,!0),document.removeEventListener("pointerdown",this.handleOutsideClick,!0),this.pickerclose.emit({}),e&&this.triggerEl?.focus())};get safeDays(){return Array.isArray(this.days)?this.days:[]}selectDay(e){e.occupied||(this.planassign.emit({recipeId:this.recipeId,day:e.day}),this.closePanel(!0))}focusIndex(e){const s=this.safeDays.length;0!==s&&(this.activeIndex=(e+s)%s,this.dayEls[this.activeIndex]?.focus())}handlePanelKeydown=e=>{switch(e.key){case"ArrowDown":e.preventDefault(),this.focusIndex(this.activeIndex+1);break;case"ArrowUp":e.preventDefault(),this.focusIndex(this.activeIndex-1);break;case"Home":e.preventDefault(),this.focusIndex(0);break;case"End":e.preventDefault(),this.focusIndex(this.safeDays.length-1);break;case"Tab":e.preventDefault();break;case"Escape":e.preventDefault(),this.closePanel(!0)}};render(){const{isOpen:e,activeIndex:s}=this,i=this.safeDays;return t(r,{key:"
|
|
1
|
+
import{proxyCustomElement as e,HTMLElement as s,createEvent as i,h as t,Host as r,transformTag as a}from"@stencil/core/internal/client";import{C as n,a as o}from"./icons.js";const c=e(class extends s{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.planassign=i(this,"planassign",7),this.pickerclose=i(this,"pickerclose",7)}recipeId;days;label;planassign;pickerclose;isOpen=!1;activeIndex=0;async open(){this.openPanel()}triggerEl;panelEl;dayEls=[];reposition=()=>this.positionPanel();handleOutsideClick=e=>{const s=e.composedPath();this.triggerEl&&this.panelEl&&(s.includes(this.triggerEl)||s.includes(this.panelEl)||this.closePanel(!1))};disconnectedCallback(){window.removeEventListener("resize",this.reposition),window.removeEventListener("scroll",this.reposition,!0),document.removeEventListener("pointerdown",this.handleOutsideClick,!0)}positionPanel(){if(!this.triggerEl||!this.panelEl)return;const e=this.triggerEl.getBoundingClientRect(),s=window.innerHeight-e.bottom<320?e.top-(this.panelEl.offsetHeight||324)-4:e.bottom+4;this.panelEl.style.left=e.left+"px",this.panelEl.style.top=s+"px"}openPanel=()=>{this.isOpen=!0,this.activeIndex=0,requestAnimationFrame((()=>{this.panelEl?.showPopover?.(),this.positionPanel(),this.dayEls[0]?.focus(),window.addEventListener("resize",this.reposition),window.addEventListener("scroll",this.reposition,!0),document.addEventListener("pointerdown",this.handleOutsideClick,!0)}))};closePanel=e=>{this.isOpen&&(this.isOpen=!1,this.panelEl?.hidePopover?.(),window.removeEventListener("resize",this.reposition),window.removeEventListener("scroll",this.reposition,!0),document.removeEventListener("pointerdown",this.handleOutsideClick,!0),this.pickerclose.emit({}),e&&this.triggerEl?.focus())};get safeDays(){return Array.isArray(this.days)?this.days:[]}selectDay(e){e.occupied||(this.planassign.emit({recipeId:this.recipeId,day:e.day}),this.closePanel(!0))}focusIndex(e){const s=this.safeDays.length;0!==s&&(this.activeIndex=(e+s)%s,this.dayEls[this.activeIndex]?.focus())}handlePanelKeydown=e=>{switch(e.key){case"ArrowDown":e.preventDefault(),this.focusIndex(this.activeIndex+1);break;case"ArrowUp":e.preventDefault(),this.focusIndex(this.activeIndex-1);break;case"Home":e.preventDefault(),this.focusIndex(0);break;case"End":e.preventDefault(),this.focusIndex(this.safeDays.length-1);break;case"Tab":e.preventDefault();break;case"Escape":e.preventDefault(),this.closePanel(!0)}};render(){const{isOpen:e,activeIndex:s}=this,i=this.safeDays;return t(r,{key:"3ab4eccd8320c8e19b5b5a73970e9fe62b3f7ce9"},t("button",{key:"dc1027c9f6dc851e11ea48ddf6adf7124347ea66",type:"button",part:"trigger",class:"trigger",ref:e=>this.triggerEl=e,"aria-haspopup":"true","aria-expanded":e?"true":"false",onClick:()=>this.isOpen?this.closePanel(!0):this.openPanel()},n(),t("span",{key:"8664507ef20182df8cd6b9bf71be7962c788a752"},this.label)),t("div",{key:"3b36e837bab0ae7afb66220a5006d2f48571502a",part:"panel",class:"panel",popover:"manual",role:"group","aria-label":this.label,ref:e=>this.panelEl=e,onKeyDown:this.handlePanelKeydown},i.map(((e,i)=>t("button",{type:"button",part:"day",class:{day:!0,occupied:e.occupied},tabIndex:i===s?0:-1,"aria-disabled":e.occupied?"true":"false",ref:e=>{e&&(this.dayEls[i]=e)},onClick:()=>this.selectDay(e)},t("span",{class:"day-label"},e.label),e.occupied&&t("span",{class:"occupied-tag"},o(),"Already added"))))))}static get style(){return":host{display:inline-block;font-family:var(--rc-font-text, system-ui, sans-serif)}.trigger{display:inline-flex;align-items:center;gap:var(--rc-s-2, 0.5rem);height:36px;padding-inline:var(--rc-s-3, 0.75rem);min-width:44px;min-height:44px;background:transparent;color:var(--rc-text, #2a2420);border:1px solid var(--rc-border-strong, #d4c8b8);border-radius:var(--rc-radius-sm, 6px);font-size:var(--rc-fs-sm, 0.875rem);cursor:pointer}.trigger:focus-visible{outline:none;box-shadow:var(--rc-focus-ring, 0 0 0 2px #fff, 0 0 0 4px #2a2420)}.panel{position:fixed;width:14rem;margin:0;padding:var(--rc-s-2, 0.5rem);border:1px solid var(--rc-border, #e7dfd3);border-radius:var(--rc-radius-sm, 6px);background:var(--rc-surface, #fff);box-shadow:var(--rc-shadow-hover, 0 8px 24px rgba(0, 0, 0, 0.12));color:var(--rc-text, #2a2420);font-family:var(--rc-font-text, system-ui, sans-serif)}.panel:not(:popover-open){display:none}.day{display:flex;align-items:center;justify-content:space-between;width:100%;height:44px;padding-inline:var(--rc-s-2, 0.5rem);border:none;border-radius:var(--rc-radius-sm, 6px);background:transparent;color:var(--rc-text, #2a2420);font-size:var(--rc-fs-body, 1rem);text-align:start;cursor:pointer}.day:hover,.day:focus-visible{background:var(--rc-accent-subtle, #fbede4)}.day:focus-visible{outline:none;box-shadow:var(--rc-focus-ring, 0 0 0 2px #fff, 0 0 0 4px #2a2420)}.day.occupied{color:var(--rc-text-subtle, #8f8377);cursor:default}.day.occupied:hover{background:transparent}.occupied-tag{display:inline-flex;align-items:center;gap:var(--rc-s-1, 0.25rem);font-size:var(--rc-fs-xs, 0.75rem)}"}},[513,"day-picker",{recipeId:[1,"recipe-id"],days:[16],label:[1],isOpen:[32],activeIndex:[32],open:[64]}]),d=c,l=function(){"undefined"!=typeof customElements&&["day-picker"].forEach((e=>{"day-picker"===e&&(customElements.get(a(e))||customElements.define(a(e),c))}))};export{d as DayPicker,l as defineCustomElement}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxyCustomElement as e,HTMLElement as a,h as t,Host as c,transformTag as
|
|
1
|
+
import{proxyCustomElement as e,HTMLElement as a,h as t,Host as c,transformTag as d}from"@stencil/core/internal/client";const s=e(class extends a{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow()}heading;render(){return t(c,{key:"3b2ddbba2fa39740bc1ce795d424a2931b1a8693"},t("div",{key:"d6486e957839d328626ab6b1e0bb72acc3daf0a7",part:"container",class:"container"},t("h2",{key:"ef726ffbbb0cbd6a686700d2be92aa752060201c",part:"heading",class:"heading"},this.heading),t("div",{key:"7d3c6f53bd2addfafa08cc1998759bf5b09031b5",class:"body"},t("slot",{key:"4c34739188f9ab384ee06b30071ad8dd1d416d87"})),t("div",{key:"a8aa769a214cdef7ad573946f639c30fbd4f5494",class:"action"},t("slot",{key:"88b13822d621c9d58b37f86545ed58c95c6d69f9",name:"action"}))))}static get style(){return":host{display:block}.container{display:flex;flex-direction:column;align-items:center;text-align:center;padding-block:var(--rc-s-6, 2rem);gap:var(--rc-s-3, 0.75rem);font-family:var(--rc-font-text, system-ui, sans-serif);color:var(--rc-text, #2a2420)}.heading{margin:0;font-family:var(--rc-font-display, Georgia, serif);font-size:var(--rc-fs-h3, 1.25rem)}.body{max-width:44ch;color:var(--rc-text-muted, #6b5f55)}"}},[769,"empty-state",{heading:[1]}]),n=s,r=function(){"undefined"!=typeof customElements&&["empty-state"].forEach((e=>{"empty-state"===e&&(customElements.get(d(e))||customElements.define(d(e),s))}))};export{n as EmptyState,r as defineCustomElement}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxyCustomElement as e,HTMLElement as r,createEvent as i,h as t,Host as
|
|
1
|
+
import{proxyCustomElement as e,HTMLElement as r,createEvent as i,h as t,Host as c,transformTag as a}from"@stencil/core/internal/client";import{X as s}from"./icons.js";const n=e(class extends r{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.chiptoggle=i(this,"chiptoggle",7)}label;value;dimension;chiptoggle;handleClick=()=>{this.chiptoggle.emit({dimension:this.dimension,value:this.value})};render(){return t(c,{key:"afc267485f8a1df6c6724b193b492a3a731b0f3d"},t("span",{key:"525dbc057f68a0b1c50f4ac507844dd8af965715",part:"chip",class:"chip"},t("span",{key:"c81319692c4229f0f1f074b8e9848f4ae6acc65c",class:"label"},this.label),t("button",{key:"cc9fb240c7f34998f4a285eaa64436985cc7647c",type:"button",part:"remove",class:"remove","aria-label":`Clear ${this.label} filter`,onClick:this.handleClick},s())))}static get style(){return":host{display:inline-flex;font-family:var(--rc-font-text, system-ui, sans-serif)}.chip{display:inline-flex;align-items:center;gap:var(--rc-s-1, 0.25rem);padding-inline-start:var(--rc-s-3, 0.75rem);border-radius:var(--rc-radius-full, 999px);background:var(--rc-accent-subtle, #fbede4);border:1px solid var(--rc-accent-border, #efcdb6);color:var(--rc-accent, #bc4e1c);font-size:var(--rc-fs-sm, 0.875rem)}.label{white-space:nowrap}.remove{display:flex;align-items:center;justify-content:center;width:44px;height:44px;margin-inline-start:calc(-1 * var(--rc-s-2, 0.5rem));padding:0;border:none;background:transparent;color:inherit;cursor:pointer}.remove:focus-visible{outline:none;box-shadow:var(--rc-focus-ring, 0 0 0 2px #fff, 0 0 0 4px #2a2420);border-radius:var(--rc-radius-full, 999px)}"}},[513,"filter-chip",{label:[1],value:[1],dimension:[1]}]),l=n,o=function(){"undefined"!=typeof customElements&&["filter-chip"].forEach((e=>{"filter-chip"===e&&(customElements.get(a(e))||customElements.define(a(e),n))}))};export{l as FilterChip,o as defineCustomElement}
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{transformTag as e}from"@stencil/core/internal/client";export{getAssetPath,render,setAssetPath,setNonce,setPlatformOptions}from"@stencil/core/internal/client";import{DayPicker as t}from"./day-picker.js";import{EmptyState as r}from"./empty-state.js";import{FilterChip as o}from"./filter-chip.js";import{PlannerDay as s}from"./planner-day.js";import{RecipeCard as m}from"./recipe-card.js";import{RecipeGrid as i}from"./recipe-grid.js";import{SkeletonCard as n}from"./skeleton-card.js";
|
|
1
|
+
import{transformTag as e}from"@stencil/core/internal/client";export{getAssetPath,render,setAssetPath,setNonce,setPlatformOptions}from"@stencil/core/internal/client";import{DayPicker as t}from"./day-picker.js";import{EmptyState as r}from"./empty-state.js";import{FilterChip as o}from"./filter-chip.js";import{PlannerDay as s}from"./planner-day.js";import{RecipeCard as m}from"./recipe-card.js";import{RecipeGrid as i}from"./recipe-grid.js";import{SkeletonCard as n}from"./skeleton-card.js";const p=p=>{"undefined"!=typeof customElements&&[t,r,o,s,m,i,n].forEach((t=>{customElements.get(e(t.is))||customElements.define(e(t.is),t,p)}))};export{p as defineCustomElements}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxyCustomElement as e,HTMLElement as r,createEvent as
|
|
1
|
+
import{proxyCustomElement as e,HTMLElement as r,createEvent as t,h as a,Host as s,transformTag as i}from"@stencil/core/internal/client";import{A as n,T as o,b as c}from"./icons.js";import{t as l}from"./tile-hue.js";const d=e(class extends r{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.entryremove=t(this,"entryremove",7),this.entrymoverequest=t(this,"entrymoverequest",7),this.daytoggle=t(this,"daytoggle",7),this.recipeselect=t(this,"recipeselect",7)}day;dayLabel;entries=[];collapsed=!1;entryremove;entrymoverequest;daytoggle;recipeselect;handleToggle=()=>{this.daytoggle.emit({day:this.day,collapsed:!this.collapsed})};renderThumb(e){if(e.thumbnail)return a("img",{class:"thumb",src:e.thumbnail,alt:"",loading:"lazy",decoding:"async"});const r=l(e.name);return a("span",{class:"thumb tile","aria-hidden":"true",style:{"--tile-h":r+""}},e.name.charAt(0).toUpperCase())}renderEntry(e){return a("li",{part:"entry",class:"entry",key:e.recipeId},this.renderThumb(e),a("button",{type:"button",class:"name",onClick:()=>this.recipeselect.emit({recipeId:e.recipeId})},e.name),a("div",{class:"row-actions"},a("button",{type:"button",class:"icon-button","aria-label":"Move "+e.name,onClick:()=>this.entrymoverequest.emit({recipeId:e.recipeId,fromDay:this.day})},n()),a("button",{type:"button",class:"icon-button","aria-label":`Remove ${e.name} from ${this.dayLabel}`,onClick:()=>this.entryremove.emit({recipeId:e.recipeId,day:this.day})},o())))}render(){const{collapsed:e,dayLabel:r}=this,t=Array.isArray(this.entries)?this.entries:[];return a(s,{key:"37926cf2b92f7d6e81d13ba8f3df7b6e76c58334"},a("section",{key:"32f696dbb8ba397bf224177b7fd21b1fb9933fa1",part:"region",class:"region",role:"region","aria-label":r},a("div",{key:"e021c4c19019669215d9f4322cd0b66d44436d15",part:"header",class:"header"},a("h3",{key:"0f11610477eb4b271eaa0896c4f6b009abab1bca",class:"day-name"},r),a("span",{key:"76ef1f1f2e90e0f4891f55bed6cc3366061ac82f",class:"count"},t.length),a("button",{key:"bb761382062f888e48e2ded770e9803e5caf9275",type:"button",class:{toggle:!0,"is-collapsed":e},"aria-expanded":e?"false":"true","aria-label":e?"Expand "+r:"Collapse "+r,onClick:this.handleToggle},c())),!e&&(t.length?a("ul",{class:"entries"},t.map((e=>this.renderEntry(e)))):a("div",{class:"empty"},a("slot",{name:"empty"})))))}static get style(){return":host{display:block;font-family:var(--rc-font-text, system-ui, sans-serif)}.region{display:flex;flex-direction:column;height:100%;min-height:20rem;background:var(--rc-surface-sunken, #f6f1e9);border:1px solid var(--rc-border, #e7dfd3);border-radius:var(--rc-radius, 14px);padding:var(--rc-s-4, 1rem);gap:var(--rc-s-3, 0.75rem);color:var(--rc-text, #2a2420)}.header{display:flex;align-items:center;gap:var(--rc-s-2, 0.5rem)}.day-name{margin:0;flex:1;font-family:var(--rc-font-display, Georgia, serif);font-size:var(--rc-fs-h3, 1.25rem)}.count{color:var(--rc-text-muted, #6b5f55);font-size:var(--rc-fs-sm, 0.875rem)}.toggle{display:flex;align-items:center;justify-content:center;width:44px;height:44px;padding:0;border:none;background:transparent;color:var(--rc-text-muted, #6b5f55);cursor:pointer;transition:transform var(--rc-duration, 180ms) var(--rc-ease, ease)}.toggle.is-collapsed{transform:rotate(-90deg)}.toggle:focus-visible{outline:none;box-shadow:var(--rc-focus-ring, 0 0 0 2px #fff, 0 0 0 4px #2a2420);border-radius:var(--rc-radius-sm, 6px)}.entries{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--rc-s-2, 0.5rem)}.entry{display:flex;align-items:center;gap:var(--rc-s-2, 0.5rem);padding:var(--rc-s-2, 0.5rem);background:var(--rc-surface, #fff);border:1px solid var(--rc-border, #e7dfd3);border-radius:var(--rc-radius-sm, 6px)}.thumb{flex:none;width:56px;height:56px;border-radius:var(--rc-radius-sm, 6px);object-fit:cover}.thumb.tile{display:flex;align-items:center;justify-content:center;background:hsl(var(--tile-h) 42% 88%);color:hsl(var(--tile-h) 45% 28%);font-family:var(--rc-font-display, Georgia, serif);font-size:var(--rc-fs-body, 1rem);font-weight:600}@media (prefers-color-scheme: dark){.thumb.tile{background:hsl(var(--tile-h) 30% 22%);color:hsl(var(--tile-h) 35% 82%)}}.name{flex:1;min-width:0;font-family:inherit;font-size:var(--rc-fs-sm, 0.875rem);color:inherit;background:transparent;border:none;padding:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-align:start;cursor:pointer}.name:hover{text-decoration:underline}.name:focus-visible{outline:none;box-shadow:var(--rc-focus-ring, 0 0 0 2px #fff, 0 0 0 4px #2a2420);border-radius:var(--rc-radius-sm, 6px)}.row-actions{display:flex;gap:var(--rc-s-1, 0.25rem)}.icon-button{display:flex;align-items:center;justify-content:center;width:44px;height:44px;padding:0;border:none;background:transparent;color:var(--rc-text-muted, #6b5f55);cursor:pointer}.icon-button:focus-visible{outline:none;box-shadow:var(--rc-focus-ring, 0 0 0 2px #fff, 0 0 0 4px #2a2420);border-radius:var(--rc-radius-sm, 6px)}.empty{flex:1;display:flex;align-items:center;justify-content:center;color:var(--rc-text-subtle, #8f8377);font-size:var(--rc-fs-sm, 0.875rem)}"}},[769,"planner-day",{day:[1],dayLabel:[1,"day-label"],entries:[16],collapsed:[4]}]),f=d,p=function(){"undefined"!=typeof customElements&&["planner-day"].forEach((e=>{"planner-day"===e&&(customElements.get(i(e))||customElements.define(i(e),d))}))};export{f as PlannerDay,p as defineCustomElement}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxyCustomElement as e,HTMLElement as r,createEvent as t,h as a,Host as i,transformTag as o}from"@stencil/core/internal/client";import{
|
|
1
|
+
import{proxyCustomElement as e,HTMLElement as r,createEvent as t,h as a,Host as i,transformTag as o}from"@stencil/core/internal/client";import{t as s}from"./tile-hue.js";import{H as c}from"./icons.js";const n=e(class extends r{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.favoritetoggle=t(this,"favoritetoggle",7),this.recipeselect=t(this,"recipeselect",7)}recipe;favorited=!1;href;favoritetoggle;recipeselect;handleTitleClick=e=>{0!==e.button||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||(e.preventDefault(),this.recipeselect.emit({recipeId:this.recipe.id}))};handleFavoriteClick=()=>{this.favoritetoggle.emit({recipeId:this.recipe.id})};renderMedia(){const{thumbnail:e,name:r}=this.recipe;if(e)return a("img",{part:"media",class:"media",src:e,alt:"",loading:"lazy",decoding:"async"});const t=s(r);return a("div",{part:"media",class:"media tile",style:{"--tile-h":t+""}},a("span",{class:"tile-name"},r))}render(){const{recipe:e,favorited:r,href:t}=this;return e&&"object"==typeof e?a(i,null,a("article",{part:"card",class:"card"},this.renderMedia(),a("div",{class:"body"},a("a",{part:"title",class:"title",href:t,onClick:this.handleTitleClick},e.name),a("p",{class:"meta"},[e.category,e.area].filter(Boolean).join(" · ")),a("div",{class:"actions-row"},a("button",{type:"button",class:"favorite","aria-pressed":r?"true":"false","aria-label":r?`Remove ${e.name} from favorites`:`Add ${e.name} to favorites`,onClick:this.handleFavoriteClick},c(r)),a("div",{part:"actions",class:"actions"},a("slot",{name:"actions"})))))):a(i,null)}static get style(){return":host{display:block;height:22rem;font-family:var(--rc-font-text, system-ui, sans-serif)}.card{display:flex;flex-direction:column;height:100%;background:var(--rc-surface, #fff);border:1px solid var(--rc-border, #e7dfd3);border-radius:var(--rc-radius, 14px);box-shadow:var(--rc-shadow, 0 1px 2px rgba(0, 0, 0, 0.06));overflow:hidden;transition:box-shadow var(--rc-duration, 180ms) var(--rc-ease, ease), border-color var(--rc-duration, 180ms) var(--rc-ease, ease), transform var(--rc-duration, 180ms) var(--rc-ease, ease)}.card:hover{box-shadow:var(--rc-shadow-hover, 0 2px 8px rgba(0, 0, 0, 0.08));border-color:var(--rc-border-strong, #d4c8b8);transform:translateY(-2px)}.media{height:12rem;flex:none;margin:0}img.media{width:100%;object-fit:cover}.media.tile{display:flex;align-items:center;justify-content:center;padding:var(--rc-s-4, 1rem);text-align:center;background:hsl(var(--tile-h) 42% 88%);color:hsl(var(--tile-h) 45% 28%)}@media (prefers-color-scheme: dark){.media.tile{background:hsl(var(--tile-h) 30% 22%);color:hsl(var(--tile-h) 35% 82%)}}.tile-name{font-family:var(--rc-font-display, Georgia, serif);font-size:var(--rc-fs-h3, 1.25rem);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.body{flex:1;min-height:0;display:flex;flex-direction:column;padding:var(--rc-s-4, 1rem);gap:var(--rc-s-2, 0.5rem)}.title{font-family:var(--rc-font-display, Georgia, serif);font-size:var(--rc-fs-h3, 1.25rem);color:var(--rc-text, #2a2420);text-decoration:none;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.title:focus-visible{outline:none;box-shadow:var(--rc-focus-ring, 0 0 0 2px #fff, 0 0 0 4px #2a2420);border-radius:var(--rc-radius-sm, 6px)}.meta{margin:0;font-size:var(--rc-fs-sm, 0.875rem);color:var(--rc-text-muted, #6b5f55)}.actions-row{margin-top:auto;display:flex;align-items:center;gap:var(--rc-s-2, 0.5rem)}.favorite{flex:none;display:flex;align-items:center;justify-content:center;width:44px;height:44px;padding:0;border:none;background:transparent;color:var(--rc-text-muted, #6b5f55);cursor:pointer;border-radius:var(--rc-radius-sm, 6px)}.favorite[aria-pressed='true']{color:var(--rc-accent, #bc4e1c)}.favorite:focus-visible{outline:none;box-shadow:var(--rc-focus-ring, 0 0 0 2px #fff, 0 0 0 4px #2a2420)}.actions{display:flex;align-items:center;gap:var(--rc-s-2, 0.5rem)}"}},[769,"recipe-card",{recipe:[16],favorited:[4],href:[1]}]),l=n,d=function(){"undefined"!=typeof customElements&&["recipe-card"].forEach((e=>{"recipe-card"===e&&(customElements.get(o(e))||customElements.define(o(e),n))}))};export{l as RecipeCard,d as defineCustomElement}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxyCustomElement as e,HTMLElement as
|
|
1
|
+
import{proxyCustomElement as e,HTMLElement as c,h as t,Host as r,transformTag as s}from"@stencil/core/internal/client";const i=e(class extends c{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow()}columns=4;render(){return t(r,{key:"2eeb8840a304c8d0bf8a11622cc28b47fe78dd5e"},t("div",{key:"c384c499908d7f6c425cb989cb0ab27519e60d40",part:"grid",class:"grid",style:{"--columns":this.columns+""}},t("slot",{key:"d373ebc3b586e86f578ca68ad072aa4b7086a199"})))}static get style(){return":host{display:block}.grid{display:grid;grid-template-columns:repeat(var(--columns), 1fr);gap:var(--rc-s-4, 1rem)}"}},[769,"recipe-grid",{columns:[2]}]),d=i,n=function(){"undefined"!=typeof customElements&&["recipe-grid"].forEach((e=>{"recipe-grid"===e&&(customElements.get(s(e))||customElements.define(s(e),i))}))};export{d as RecipeGrid,n as defineCustomElement}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxyCustomElement as e,HTMLElement as r,h as t,Host as n,transformTag as a}from"@stencil/core/internal/client";const i=e(class extends r{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow()}count=1;render(){const e=Array.from({length:Math.max(1,this.count)});return t(n,{key:"
|
|
1
|
+
import{proxyCustomElement as e,HTMLElement as r,h as t,Host as n,transformTag as a}from"@stencil/core/internal/client";const i=e(class extends r{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow()}count=1;render(){const e=Array.from({length:Math.max(1,this.count)});return t(n,{key:"a627b85c34fc85c3f2a448c87cbcc3f027594452"},e.map(((e,r)=>t("div",{part:"skeleton",class:"skeleton",key:r,"aria-hidden":"true"},t("div",{class:"media"}),t("div",{class:"body"},t("div",{class:"line title"}),t("div",{class:"line meta"}))))))}static get style(){return":host{display:contents}.skeleton{height:22rem;display:flex;flex-direction:column;background:var(--rc-surface, #fff);border:1px solid var(--rc-border, #e7dfd3);border-radius:var(--rc-radius, 14px);overflow:hidden}.media{height:12rem;flex:none;background:var(--rc-surface-sunken, #f6f1e9);position:relative;overflow:hidden}.body{flex:1;padding:var(--rc-s-4, 1rem);display:flex;flex-direction:column;gap:var(--rc-s-2, 0.5rem)}.line{border-radius:var(--rc-radius-sm, 6px);background:var(--rc-surface-sunken, #f6f1e9);position:relative;overflow:hidden}.line.title{height:1.25rem;width:70%}.line.meta{height:0.875rem;width:45%}.media::after,.line::after{content:'';position:absolute;inset:0;background:linear-gradient(90deg, transparent, var(--rc-border, #e7dfd3) 50%, transparent);opacity:0.3;animation:shimmer 1.4s infinite}@keyframes shimmer{from{transform:translateX(-100%)}to{transform:translateX(100%)}}@media (prefers-reduced-motion: reduce){.media::after,.line::after{animation:none;transform:none;opacity:0.2}}"}},[513,"skeleton-card",{count:[2]}]),s=i,o=function(){"undefined"!=typeof customElements&&["skeleton-card"].forEach((e=>{"skeleton-card"===e&&(customElements.get(a(e))||customElements.define(a(e),i))}))};export{s as SkeletonCard,o as defineCustomElement}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t=[18,34,96,168,262,344];function e(e){let n=0;for(let t=0;t<e.length;t++)n+=e.charCodeAt(t);return t[n%t.length]}export{e as t}
|
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { HTMLStencilElement, JSXBase } from "./stencil-public-runtime";
|
|
8
8
|
import { DayOfWeek, DayOption, PlannerEntry, RecipeSummary } from "./utils/types";
|
|
9
|
-
import { SpikeNote } from "./components/spike-panel/spike-panel";
|
|
10
9
|
export { DayOfWeek, DayOption, PlannerEntry, RecipeSummary } from "./utils/types";
|
|
11
|
-
export { SpikeNote } from "./components/spike-panel/spike-panel";
|
|
12
10
|
export namespace Components {
|
|
13
11
|
/**
|
|
14
12
|
* Assigns a recipe to a day of the plan. Stateless: occupancy is an input
|
|
@@ -101,17 +99,6 @@ export namespace Components {
|
|
|
101
99
|
*/
|
|
102
100
|
"count": number;
|
|
103
101
|
}
|
|
104
|
-
/**
|
|
105
|
-
* Integration spike only. Proves the Stencil <-> SvelteKit seam (object
|
|
106
|
-
* property, custom event, slot) end to end. Not part of the real component
|
|
107
|
-
* set to come.
|
|
108
|
-
*/
|
|
109
|
-
interface SpikePanel {
|
|
110
|
-
/**
|
|
111
|
-
* Arrives as an object property once the element has upgraded.
|
|
112
|
-
*/
|
|
113
|
-
"note"?: SpikeNote;
|
|
114
|
-
}
|
|
115
102
|
}
|
|
116
103
|
export interface DayPickerCustomEvent<T> extends CustomEvent<T> {
|
|
117
104
|
detail: T;
|
|
@@ -129,10 +116,6 @@ export interface RecipeCardCustomEvent<T> extends CustomEvent<T> {
|
|
|
129
116
|
detail: T;
|
|
130
117
|
target: HTMLRecipeCardElement;
|
|
131
118
|
}
|
|
132
|
-
export interface SpikePanelCustomEvent<T> extends CustomEvent<T> {
|
|
133
|
-
detail: T;
|
|
134
|
-
target: HTMLSpikePanelElement;
|
|
135
|
-
}
|
|
136
119
|
declare global {
|
|
137
120
|
interface HTMLDayPickerElementEventMap {
|
|
138
121
|
"planassign": { recipeId: string; day: DayOfWeek };
|
|
@@ -267,28 +250,6 @@ declare global {
|
|
|
267
250
|
prototype: HTMLSkeletonCardElement;
|
|
268
251
|
new (): HTMLSkeletonCardElement;
|
|
269
252
|
};
|
|
270
|
-
interface HTMLSpikePanelElementEventMap {
|
|
271
|
-
"spikeaction": SpikeNote;
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Integration spike only. Proves the Stencil <-> SvelteKit seam (object
|
|
275
|
-
* property, custom event, slot) end to end. Not part of the real component
|
|
276
|
-
* set to come.
|
|
277
|
-
*/
|
|
278
|
-
interface HTMLSpikePanelElement extends Components.SpikePanel, HTMLStencilElement {
|
|
279
|
-
addEventListener<K extends keyof HTMLSpikePanelElementEventMap>(type: K, listener: (this: HTMLSpikePanelElement, ev: SpikePanelCustomEvent<HTMLSpikePanelElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
|
280
|
-
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
281
|
-
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
282
|
-
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
283
|
-
removeEventListener<K extends keyof HTMLSpikePanelElementEventMap>(type: K, listener: (this: HTMLSpikePanelElement, ev: SpikePanelCustomEvent<HTMLSpikePanelElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
|
284
|
-
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
285
|
-
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
286
|
-
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
287
|
-
}
|
|
288
|
-
var HTMLSpikePanelElement: {
|
|
289
|
-
prototype: HTMLSpikePanelElement;
|
|
290
|
-
new (): HTMLSpikePanelElement;
|
|
291
|
-
};
|
|
292
253
|
interface HTMLElementTagNameMap {
|
|
293
254
|
"day-picker": HTMLDayPickerElement;
|
|
294
255
|
"empty-state": HTMLEmptyStateElement;
|
|
@@ -297,7 +258,6 @@ declare global {
|
|
|
297
258
|
"recipe-card": HTMLRecipeCardElement;
|
|
298
259
|
"recipe-grid": HTMLRecipeGridElement;
|
|
299
260
|
"skeleton-card": HTMLSkeletonCardElement;
|
|
300
|
-
"spike-panel": HTMLSpikePanelElement;
|
|
301
261
|
}
|
|
302
262
|
}
|
|
303
263
|
declare namespace LocalJSX {
|
|
@@ -399,21 +359,6 @@ declare namespace LocalJSX {
|
|
|
399
359
|
*/
|
|
400
360
|
"count"?: number;
|
|
401
361
|
}
|
|
402
|
-
/**
|
|
403
|
-
* Integration spike only. Proves the Stencil <-> SvelteKit seam (object
|
|
404
|
-
* property, custom event, slot) end to end. Not part of the real component
|
|
405
|
-
* set to come.
|
|
406
|
-
*/
|
|
407
|
-
interface SpikePanel {
|
|
408
|
-
/**
|
|
409
|
-
* Arrives as an object property once the element has upgraded.
|
|
410
|
-
*/
|
|
411
|
-
"note"?: SpikeNote;
|
|
412
|
-
/**
|
|
413
|
-
* Lowercase, so it binds as a plain Svelte `on*` attribute.
|
|
414
|
-
*/
|
|
415
|
-
"onSpikeaction"?: (event: SpikePanelCustomEvent<SpikeNote>) => void;
|
|
416
|
-
}
|
|
417
362
|
|
|
418
363
|
interface DayPickerAttributes {
|
|
419
364
|
"recipeId": string;
|
|
@@ -451,7 +396,6 @@ declare namespace LocalJSX {
|
|
|
451
396
|
"recipe-card": Omit<RecipeCard, keyof RecipeCardAttributes> & { [K in keyof RecipeCard & keyof RecipeCardAttributes]?: RecipeCard[K] } & { [K in keyof RecipeCard & keyof RecipeCardAttributes as `attr:${K}`]?: RecipeCardAttributes[K] } & { [K in keyof RecipeCard & keyof RecipeCardAttributes as `prop:${K}`]?: RecipeCard[K] } & OneOf<"href", RecipeCard["href"], RecipeCardAttributes["href"]>;
|
|
452
397
|
"recipe-grid": Omit<RecipeGrid, keyof RecipeGridAttributes> & { [K in keyof RecipeGrid & keyof RecipeGridAttributes]?: RecipeGrid[K] } & { [K in keyof RecipeGrid & keyof RecipeGridAttributes as `attr:${K}`]?: RecipeGridAttributes[K] } & { [K in keyof RecipeGrid & keyof RecipeGridAttributes as `prop:${K}`]?: RecipeGrid[K] };
|
|
453
398
|
"skeleton-card": Omit<SkeletonCard, keyof SkeletonCardAttributes> & { [K in keyof SkeletonCard & keyof SkeletonCardAttributes]?: SkeletonCard[K] } & { [K in keyof SkeletonCard & keyof SkeletonCardAttributes as `attr:${K}`]?: SkeletonCardAttributes[K] } & { [K in keyof SkeletonCard & keyof SkeletonCardAttributes as `prop:${K}`]?: SkeletonCard[K] };
|
|
454
|
-
"spike-panel": SpikePanel;
|
|
455
399
|
}
|
|
456
400
|
}
|
|
457
401
|
export { LocalJSX as JSX };
|
|
@@ -507,12 +451,6 @@ declare module "@stencil/core" {
|
|
|
507
451
|
* not shift when real cards arrive.
|
|
508
452
|
*/
|
|
509
453
|
"skeleton-card": LocalJSX.IntrinsicElements["skeleton-card"] & JSXBase.HTMLAttributes<HTMLSkeletonCardElement>;
|
|
510
|
-
/**
|
|
511
|
-
* Integration spike only. Proves the Stencil <-> SvelteKit seam (object
|
|
512
|
-
* property, custom event, slot) end to end. Not part of the real component
|
|
513
|
-
* set to come.
|
|
514
|
-
*/
|
|
515
|
-
"spike-panel": LocalJSX.IntrinsicElements["spike-panel"] & JSXBase.HTMLAttributes<HTMLSpikePanelElement>;
|
|
516
454
|
}
|
|
517
455
|
}
|
|
518
456
|
}
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -26,9 +26,17 @@ defineCustomElements();
|
|
|
26
26
|
|
|
27
27
|
Register once, client-side only, before any consumer renders.
|
|
28
28
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
## Components
|
|
30
|
+
|
|
31
|
+
| Component | Purpose |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `<recipe-card>` | A single recipe summary — thumbnail or typographic tile, favorite toggle, `actions` slot |
|
|
34
|
+
| `<recipe-grid>` | Responsive card grid layout |
|
|
35
|
+
| `<filter-chip>` | A removable active-filter chip |
|
|
36
|
+
| `<day-picker>` | Assign a recipe to a day of the week |
|
|
37
|
+
| `<planner-day>` | One day's column/section in the weekly planner |
|
|
38
|
+
| `<empty-state>` | Empty/zero-result state with an optional action slot |
|
|
39
|
+
| `<skeleton-card>` | Loading placeholder matching `<recipe-card>`'s dimensions |
|
|
40
|
+
|
|
41
|
+
Every component reads its theme from `--rc-*` CSS custom properties, each with a built-in
|
|
42
|
+
fallback, so it renders correctly even when the consuming app defines none of them.
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Components, JSX } from "../types/components";
|
|
2
|
-
|
|
3
|
-
interface SpikePanel extends Components.SpikePanel, HTMLElement {}
|
|
4
|
-
export const SpikePanel: {
|
|
5
|
-
prototype: SpikePanel;
|
|
6
|
-
new (): SpikePanel;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Used to define this component and all nested components recursively.
|
|
10
|
-
*/
|
|
11
|
-
export const defineCustomElement: () => void;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{proxyCustomElement as e,HTMLElement as t,createEvent as s,h as i,Host as n,transformTag as o}from"@stencil/core/internal/client";const a=e(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.spikeaction=s(this,"spikeaction",7)}note;spikeaction;handleClick=()=>{this.spikeaction.emit(this.note??{from:"spike-panel",message:"no note received"})};render(){return i(n,{key:"e2dd4e5cab4edda56f9b23b1da25af36f3f65c84"},i("p",{key:"0ba3c3d40ee49b765eef7af8af438d3b9f5d71fe"},this.note?`From ${this.note.from}: ${this.note.message}`:"Waiting for an object property..."),i("button",{key:"082230f40c2dd4180f3d6552ebd5133fe90531aa",type:"button",onClick:this.handleClick},"Emit spikeaction"),i("div",{key:"f72d1123a8aed1af44d866e5f3c46d77b960ad9a",class:"slot-wrap"},i("slot",{key:"0369ec7f60e0e368eb7630eb00d4d70cc8563204"})))}static get style(){return":host{display:block;border:1px solid #ccc;border-radius:8px;padding:1rem;font-family:system-ui, sans-serif}button{cursor:pointer}.slot-wrap{margin-top:0.75rem}"}},[769,"spike-panel",{note:[16]}]),r=a,c=function(){"undefined"!=typeof customElements&&["spike-panel"].forEach((e=>{"spike-panel"===e&&(customElements.get(o(e))||customElements.define(o(e),a))}))};export{r as SpikePanel,c as defineCustomElement}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
|
-
export interface SpikeNote {
|
|
3
|
-
from: string;
|
|
4
|
-
message: string;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Integration spike only. Proves the Stencil <-> SvelteKit seam (object
|
|
8
|
-
* property, custom event, slot) end to end. Not part of the real component
|
|
9
|
-
* set to come.
|
|
10
|
-
*/
|
|
11
|
-
export declare class SpikePanel {
|
|
12
|
-
/** Arrives as an object property once the element has upgraded. */
|
|
13
|
-
note?: SpikeNote;
|
|
14
|
-
/** Lowercase, so it binds as a plain Svelte `on*` attribute. */
|
|
15
|
-
spikeaction: EventEmitter<SpikeNote>;
|
|
16
|
-
private handleClick;
|
|
17
|
-
render(): any;
|
|
18
|
-
}
|