recipe-planner-ui 1.1.1 → 1.3.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/cjs/{index-B6uIqnrk.js → index-CrJlwqe_.js} +103 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/recipe-planner-ui.cjs.js +2 -2
- package/dist/cjs/rp-day-slot.cjs.entry.js +77 -9
- package/dist/cjs/rp-filter-chips_5.cjs.entry.js +44 -13
- package/dist/cjs/rp-filter-menu.cjs.entry.js +143 -0
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/rp-day-slot/rp-day-slot.css +191 -23
- package/dist/collection/components/rp-day-slot/rp-day-slot.js +83 -11
- package/dist/collection/components/rp-filter-chips/rp-filter-chips.css +35 -3
- package/dist/collection/components/rp-filter-chips/rp-filter-chips.js +1 -1
- package/dist/collection/components/rp-filter-menu/rp-filter-menu.css +272 -0
- package/dist/collection/components/rp-filter-menu/rp-filter-menu.js +331 -0
- package/dist/collection/components/rp-ingredient-list/rp-ingredient-list.css +39 -9
- package/dist/collection/components/rp-ingredient-list/rp-ingredient-list.js +2 -2
- package/dist/collection/components/rp-modal/rp-modal.css +65 -12
- package/dist/collection/components/rp-modal/rp-modal.js +1 -1
- package/dist/collection/components/rp-recipe-card/rp-recipe-card.css +201 -17
- package/dist/collection/components/rp-recipe-card/rp-recipe-card.js +78 -2
- package/dist/collection/components/rp-search-bar/rp-search-bar.css +100 -18
- package/dist/collection/components/rp-search-bar/rp-search-bar.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/rp-day-slot.js +1 -1
- package/dist/components/rp-filter-chips.js +1 -1
- package/dist/components/rp-filter-menu.d.ts +11 -0
- package/dist/components/rp-filter-menu.js +1 -0
- package/dist/components/rp-ingredient-list.js +1 -1
- package/dist/components/rp-modal.js +1 -1
- package/dist/components/rp-recipe-card.js +1 -1
- package/dist/components/rp-search-bar.js +1 -1
- package/dist/esm/{index-B4wAFfci.js → index-xM9qpraa.js} +103 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/recipe-planner-ui.js +3 -3
- package/dist/esm/rp-day-slot.entry.js +77 -9
- package/dist/esm/rp-filter-chips_5.entry.js +44 -13
- package/dist/esm/rp-filter-menu.entry.js +141 -0
- package/dist/recipe-planner-ui/p-811d8206.entry.js +1 -0
- package/dist/recipe-planner-ui/p-9018ce87.entry.js +1 -0
- package/dist/recipe-planner-ui/p-9e84a578.entry.js +1 -0
- package/dist/recipe-planner-ui/p-xM9qpraa.js +3 -0
- package/dist/recipe-planner-ui/recipe-planner-ui.css +6 -1
- package/dist/recipe-planner-ui/recipe-planner-ui.esm.js +1 -1
- package/dist/types/components/rp-day-slot/rp-day-slot.d.ts +22 -3
- package/dist/types/components/rp-filter-menu/rp-filter-menu.d.ts +60 -0
- package/dist/types/components/rp-recipe-card/rp-recipe-card.d.ts +20 -0
- package/dist/types/components.d.ts +175 -9
- package/package.json +1 -1
- package/dist/recipe-planner-ui/p-0c8f7438.entry.js +0 -1
- package/dist/recipe-planner-ui/p-B4wAFfci.js +0 -3
- package/dist/recipe-planner-ui/p-b98e7093.entry.js +0 -1
|
@@ -152,6 +152,23 @@ var plt = {
|
|
|
152
152
|
ce: (eventName, opts) => new CustomEvent(eventName, opts)
|
|
153
153
|
};
|
|
154
154
|
var supportsShadow = BUILD.shadowDom;
|
|
155
|
+
var supportsListenerOptions = /* @__PURE__ */ (() => {
|
|
156
|
+
var _a;
|
|
157
|
+
let supportsListenerOptions2 = false;
|
|
158
|
+
try {
|
|
159
|
+
(_a = win.document) == null ? void 0 : _a.addEventListener(
|
|
160
|
+
"e",
|
|
161
|
+
null,
|
|
162
|
+
Object.defineProperty({}, "passive", {
|
|
163
|
+
get() {
|
|
164
|
+
supportsListenerOptions2 = true;
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
);
|
|
168
|
+
} catch (e) {
|
|
169
|
+
}
|
|
170
|
+
return supportsListenerOptions2;
|
|
171
|
+
})();
|
|
155
172
|
var promiseResolve = (v) => Promise.resolve(v);
|
|
156
173
|
var supportsConstructableStylesheets = /* @__PURE__ */ (() => {
|
|
157
174
|
try {
|
|
@@ -591,6 +608,9 @@ var parsePropertyValue = (propValue, propType, isFormAssociated) => {
|
|
|
591
608
|
return propValue === "false" ? false : propValue === "" || !!propValue;
|
|
592
609
|
}
|
|
593
610
|
}
|
|
611
|
+
if (propType & 2 /* Number */) {
|
|
612
|
+
return typeof propValue === "string" ? parseFloat(propValue) : typeof propValue === "number" ? propValue : NaN;
|
|
613
|
+
}
|
|
594
614
|
if (propType & 1 /* String */) {
|
|
595
615
|
return String(propValue);
|
|
596
616
|
}
|
|
@@ -636,7 +656,11 @@ var setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialRen
|
|
|
636
656
|
classList.remove(...oldClasses.filter((c) => c && !newClasses.includes(c)));
|
|
637
657
|
classList.add(...newClasses.filter((c) => c && !oldClasses.includes(c)));
|
|
638
658
|
}
|
|
639
|
-
} else if (memberName === "key") ; else if (
|
|
659
|
+
} else if (memberName === "key") ; else if (memberName === "ref") {
|
|
660
|
+
if (newValue) {
|
|
661
|
+
queueRefAttachment(newValue, elm);
|
|
662
|
+
}
|
|
663
|
+
} else if ((!isProp ) && memberName[0] === "o" && memberName[1] === "n") {
|
|
640
664
|
if (memberName[2] === "-") {
|
|
641
665
|
memberName = memberName.slice(3);
|
|
642
666
|
} else if (isMemberInElement(win, ln)) {
|
|
@@ -780,6 +804,8 @@ var useNativeShadowDom = false;
|
|
|
780
804
|
var checkSlotFallbackVisibility = false;
|
|
781
805
|
var checkSlotRelocate = false;
|
|
782
806
|
var isSvgMode = false;
|
|
807
|
+
var refCallbacksToRemove = [];
|
|
808
|
+
var refCallbacksToAttach = [];
|
|
783
809
|
var createElm = (oldParentVNode, newParentVNode, childIndex) => {
|
|
784
810
|
var _a;
|
|
785
811
|
const newVNode2 = newParentVNode.$children$[childIndex];
|
|
@@ -932,6 +958,7 @@ var removeVnodes = (vnodes, startIdx, endIdx) => {
|
|
|
932
958
|
const vnode = vnodes[index];
|
|
933
959
|
if (vnode) {
|
|
934
960
|
const elm = vnode.$elm$;
|
|
961
|
+
nullifyVNodeRefs(vnode);
|
|
935
962
|
if (elm) {
|
|
936
963
|
{
|
|
937
964
|
checkSlotFallbackVisibility = true;
|
|
@@ -1152,6 +1179,27 @@ var markSlotContentForRelocation = (elm) => {
|
|
|
1152
1179
|
}
|
|
1153
1180
|
}
|
|
1154
1181
|
};
|
|
1182
|
+
var nullifyVNodeRefs = (vNode) => {
|
|
1183
|
+
{
|
|
1184
|
+
if (vNode.$attrs$ && vNode.$attrs$.ref) {
|
|
1185
|
+
refCallbacksToRemove.push(() => vNode.$attrs$.ref(null));
|
|
1186
|
+
}
|
|
1187
|
+
vNode.$children$ && vNode.$children$.map(nullifyVNodeRefs);
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
var queueRefAttachment = (refCallback, elm) => {
|
|
1191
|
+
{
|
|
1192
|
+
refCallbacksToAttach.push(() => refCallback(elm));
|
|
1193
|
+
}
|
|
1194
|
+
};
|
|
1195
|
+
var flushQueuedRefCallbacks = () => {
|
|
1196
|
+
{
|
|
1197
|
+
refCallbacksToRemove.forEach((cb) => cb());
|
|
1198
|
+
refCallbacksToRemove.length = 0;
|
|
1199
|
+
refCallbacksToAttach.forEach((cb) => cb());
|
|
1200
|
+
refCallbacksToAttach.length = 0;
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1155
1203
|
var insertBefore = (parent, newNode, reference, isInitialLoad) => {
|
|
1156
1204
|
{
|
|
1157
1205
|
if (typeof newNode["s-sn"] === "string" && !!newNode["s-sr"] && !!newNode["s-cr"]) {
|
|
@@ -1321,6 +1369,7 @@ var renderVdom = (hostRef, renderFnResults, isInitialLoad = false) => {
|
|
|
1321
1369
|
}
|
|
1322
1370
|
}
|
|
1323
1371
|
contentRef = void 0;
|
|
1372
|
+
flushQueuedRefCallbacks();
|
|
1324
1373
|
};
|
|
1325
1374
|
|
|
1326
1375
|
// src/runtime/update-component.ts
|
|
@@ -1370,6 +1419,13 @@ var dispatchHooks = (hostRef, isInitialLoad) => {
|
|
|
1370
1419
|
hostRef.$deferredConnectedCallback$ = false;
|
|
1371
1420
|
safeCall(instance, "connectedCallback", void 0, elm);
|
|
1372
1421
|
}
|
|
1422
|
+
{
|
|
1423
|
+
hostRef.$flags$ |= 256 /* isListenReady */;
|
|
1424
|
+
if (hostRef.$queuedListeners$) {
|
|
1425
|
+
hostRef.$queuedListeners$.map(([methodName, event]) => safeCall(instance, methodName, event, elm));
|
|
1426
|
+
hostRef.$queuedListeners$ = void 0;
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1373
1429
|
if (hostRef.$fetchedCbList$.length) {
|
|
1374
1430
|
hostRef.$fetchedCbList$.forEach((cb) => cb(elm));
|
|
1375
1431
|
}
|
|
@@ -1853,6 +1909,7 @@ var connectedCallback = (elm) => {
|
|
|
1853
1909
|
initializeComponent(elm, hostRef, cmpMeta);
|
|
1854
1910
|
}
|
|
1855
1911
|
} else {
|
|
1912
|
+
addHostEventListeners(elm, hostRef, cmpMeta.$listeners$);
|
|
1856
1913
|
if (hostRef == null ? void 0 : hostRef.$lazyInstance$) {
|
|
1857
1914
|
fireConnectedCallback(hostRef.$lazyInstance$, elm);
|
|
1858
1915
|
} else if (hostRef.$flags$ & 1024 /* hasFailedLoad */) {
|
|
@@ -1882,6 +1939,12 @@ var disconnectInstance = (instance, elm) => {
|
|
|
1882
1939
|
var disconnectedCallback = async (elm) => {
|
|
1883
1940
|
if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
|
|
1884
1941
|
const hostRef = getHostRef(elm);
|
|
1942
|
+
{
|
|
1943
|
+
if (hostRef == null ? void 0 : hostRef.$rmListeners$) {
|
|
1944
|
+
hostRef.$rmListeners$.map((rmListener) => rmListener());
|
|
1945
|
+
hostRef.$rmListeners$ = void 0;
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1885
1948
|
if (hostRef == null ? void 0 : hostRef.$lazyInstance$) {
|
|
1886
1949
|
disconnectInstance(hostRef.$lazyInstance$, elm);
|
|
1887
1950
|
} else if (hostRef == null ? void 0 : hostRef.$onReadyPromise$) {
|
|
@@ -1931,6 +1994,9 @@ var bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
1931
1994
|
{
|
|
1932
1995
|
cmpMeta.$members$ = compactMeta[2];
|
|
1933
1996
|
}
|
|
1997
|
+
{
|
|
1998
|
+
cmpMeta.$listeners$ = compactMeta[3];
|
|
1999
|
+
}
|
|
1934
2000
|
{
|
|
1935
2001
|
cmpMeta.$attrsToReflect$ = [];
|
|
1936
2002
|
}
|
|
@@ -1957,6 +2023,7 @@ var bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
1957
2023
|
}
|
|
1958
2024
|
if (!this.hasRegisteredEventListeners) {
|
|
1959
2025
|
this.hasRegisteredEventListeners = true;
|
|
2026
|
+
addHostEventListeners(this, hostRef, cmpMeta.$listeners$);
|
|
1960
2027
|
}
|
|
1961
2028
|
if (appLoadFallback) {
|
|
1962
2029
|
clearTimeout(appLoadFallback);
|
|
@@ -2026,6 +2093,41 @@ var bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
2026
2093
|
}
|
|
2027
2094
|
endBootstrap();
|
|
2028
2095
|
};
|
|
2096
|
+
var addHostEventListeners = (elm, hostRef, listeners, attachParentListeners) => {
|
|
2097
|
+
if (listeners && win.document) {
|
|
2098
|
+
listeners.map(([flags, name, method]) => {
|
|
2099
|
+
const target = getHostListenerTarget(win.document, elm, flags) ;
|
|
2100
|
+
const handler = hostListenerProxy(hostRef, method);
|
|
2101
|
+
const opts = hostListenerOpts(flags);
|
|
2102
|
+
plt.ael(target, name, handler, opts);
|
|
2103
|
+
(hostRef.$rmListeners$ = hostRef.$rmListeners$ || []).push(() => plt.rel(target, name, handler, opts));
|
|
2104
|
+
});
|
|
2105
|
+
}
|
|
2106
|
+
};
|
|
2107
|
+
var hostListenerProxy = (hostRef, methodName) => (ev) => {
|
|
2108
|
+
var _a;
|
|
2109
|
+
try {
|
|
2110
|
+
{
|
|
2111
|
+
if (hostRef.$flags$ & 256 /* isListenReady */) {
|
|
2112
|
+
(_a = hostRef.$lazyInstance$) == null ? void 0 : _a[methodName](ev);
|
|
2113
|
+
} else {
|
|
2114
|
+
(hostRef.$queuedListeners$ = hostRef.$queuedListeners$ || []).push([methodName, ev]);
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
} catch (e) {
|
|
2118
|
+
consoleError(e, hostRef.$hostElement$);
|
|
2119
|
+
}
|
|
2120
|
+
};
|
|
2121
|
+
var getHostListenerTarget = (doc, elm, flags) => {
|
|
2122
|
+
if (flags & 4 /* TargetDocument */) {
|
|
2123
|
+
return doc;
|
|
2124
|
+
}
|
|
2125
|
+
return elm;
|
|
2126
|
+
};
|
|
2127
|
+
var hostListenerOpts = (flags) => supportsListenerOptions ? {
|
|
2128
|
+
passive: (flags & 1 /* Passive */) !== 0,
|
|
2129
|
+
capture: (flags & 2 /* Capture */) !== 0
|
|
2130
|
+
} : (flags & 2 /* Capture */) !== 0;
|
|
2029
2131
|
|
|
2030
2132
|
// src/runtime/nonce.ts
|
|
2031
2133
|
var setNonce = (nonce) => plt.$nonce$ = nonce;
|
package/dist/cjs/loader.cjs.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-CrJlwqe_.js');
|
|
4
4
|
var appGlobals = require('./app-globals-V2Kpy_OQ.js');
|
|
5
5
|
|
|
6
6
|
const defineCustomElements = async (win, options) => {
|
|
7
7
|
if (typeof window === 'undefined') return undefined;
|
|
8
8
|
await appGlobals.globalScripts();
|
|
9
|
-
return index.bootstrapLazy([["rp-filter-chips_5.cjs",[[514,"rp-filter-chips",{"options":[16],"selected":[1],"label":[1]}],[774,"rp-ingredient-list",{"items":[16]}],[774,"rp-modal",{"open":[516],"heading":[1],"focusFirstField":[64]},null,{"open":[{"onOpenChange":0}]}],[774,"rp-recipe-card",{"recipeId":[1,"recipe-id"],"recipeTitle":[1,"recipe-title"],"image":[1],"category":[1],"favorite":[516]}],[514,"rp-search-bar",{"value":[1],"placeholder":[1],"label":[1],"draft":[32]},null,{"value":[{"onValueChange":0}]}]]],["rp-day-slot.cjs",[[774,"rp-day-slot",{"day":[1],"dayLabel":[1,"day-label"],"meals":[16],"days":[16],"dayLabels":[16],"normalized":[32]}]]]], options);
|
|
9
|
+
return index.bootstrapLazy([["rp-filter-chips_5.cjs",[[514,"rp-filter-chips",{"options":[16],"selected":[1],"label":[1]}],[774,"rp-ingredient-list",{"items":[16]}],[774,"rp-modal",{"open":[516],"heading":[1],"focusFirstField":[64]},null,{"open":[{"onOpenChange":0}]}],[774,"rp-recipe-card",{"recipeId":[1,"recipe-id"],"recipeTitle":[1,"recipe-title"],"image":[1],"category":[1],"area":[1],"minutes":[2],"favorite":[516],"imageLoading":[32],"imageFailed":[32],"pulsing":[32]}],[514,"rp-search-bar",{"value":[1],"placeholder":[1],"label":[1],"draft":[32]},null,{"value":[{"onValueChange":0}]}]]],["rp-day-slot.cjs",[[774,"rp-day-slot",{"day":[1],"dayLabel":[1,"day-label"],"meals":[16],"days":[16],"dayLabels":[16],"normalized":[32],"dropActive":[32],"draggingId":[32]}]]],["rp-filter-menu.cjs",[[514,"rp-filter-menu",{"label":[1],"options":[16],"selected":[1],"searchPlaceholder":[1,"search-placeholder"],"searchable":[4],"open":[1540],"filterText":[32],"activeIndex":[32]},[[5,"pointerdown","onDocumentPointerDown"],[4,"keydown","onDocumentKeydown"]],{"open":[{"onOpenChange":0}]}]]]], options);
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
exports.setNonce = index.setNonce;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-CrJlwqe_.js');
|
|
4
4
|
var appGlobals = require('./app-globals-V2Kpy_OQ.js');
|
|
5
5
|
|
|
6
6
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
@@ -19,7 +19,7 @@ var patchBrowser = () => {
|
|
|
19
19
|
|
|
20
20
|
patchBrowser().then(async (options) => {
|
|
21
21
|
await appGlobals.globalScripts();
|
|
22
|
-
return index.bootstrapLazy([["rp-filter-chips_5.cjs",[[514,"rp-filter-chips",{"options":[16],"selected":[1],"label":[1]}],[774,"rp-ingredient-list",{"items":[16]}],[774,"rp-modal",{"open":[516],"heading":[1],"focusFirstField":[64]},null,{"open":[{"onOpenChange":0}]}],[774,"rp-recipe-card",{"recipeId":[1,"recipe-id"],"recipeTitle":[1,"recipe-title"],"image":[1],"category":[1],"favorite":[516]}],[514,"rp-search-bar",{"value":[1],"placeholder":[1],"label":[1],"draft":[32]},null,{"value":[{"onValueChange":0}]}]]],["rp-day-slot.cjs",[[774,"rp-day-slot",{"day":[1],"dayLabel":[1,"day-label"],"meals":[16],"days":[16],"dayLabels":[16],"normalized":[32]}]]]], options);
|
|
22
|
+
return index.bootstrapLazy([["rp-filter-chips_5.cjs",[[514,"rp-filter-chips",{"options":[16],"selected":[1],"label":[1]}],[774,"rp-ingredient-list",{"items":[16]}],[774,"rp-modal",{"open":[516],"heading":[1],"focusFirstField":[64]},null,{"open":[{"onOpenChange":0}]}],[774,"rp-recipe-card",{"recipeId":[1,"recipe-id"],"recipeTitle":[1,"recipe-title"],"image":[1],"category":[1],"area":[1],"minutes":[2],"favorite":[516],"imageLoading":[32],"imageFailed":[32],"pulsing":[32]}],[514,"rp-search-bar",{"value":[1],"placeholder":[1],"label":[1],"draft":[32]},null,{"value":[{"onValueChange":0}]}]]],["rp-day-slot.cjs",[[774,"rp-day-slot",{"day":[1],"dayLabel":[1,"day-label"],"meals":[16],"days":[16],"dayLabels":[16],"normalized":[32],"dropActive":[32],"draggingId":[32]}]]],["rp-filter-menu.cjs",[[514,"rp-filter-menu",{"label":[1],"options":[16],"selected":[1],"searchPlaceholder":[1,"search-placeholder"],"searchable":[4],"open":[1540],"filterText":[32],"activeIndex":[32]},[[5,"pointerdown","onDocumentPointerDown"],[4,"keydown","onDocumentKeydown"]],{"open":[{"onOpenChange":0}]}]]]], options);
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
exports.setNonce = index.setNonce;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-CrJlwqe_.js');
|
|
4
4
|
|
|
5
|
-
const rpDaySlotCss = () => `.sc-rp-day-slot-h{display:block;font-family:var(--rp-font-sans);color:var(--rp-color-text)}.slot.sc-rp-day-slot{display:flex;flex-direction:column;height:100%;min-height:
|
|
5
|
+
const rpDaySlotCss = () => `.sc-rp-day-slot-h{display:block;font-family:var(--rp-font-sans);color:var(--rp-color-text)}.slot.sc-rp-day-slot{display:flex;flex-direction:column;height:100%;min-height:200px;overflow:hidden;background:var(--rp-color-surface);border:1px solid var(--rp-color-border);border-radius:var(--rp-radius-lg);box-shadow:var(--rp-shadow-xs);transition:border-color var(--rp-duration) var(--rp-ease), box-shadow var(--rp-duration) var(--rp-ease), background-color var(--rp-duration) var(--rp-ease)}.slot.is-empty.sc-rp-day-slot{background:var(--rp-color-surface-sunken);border-style:dashed}.slot.is-drop-active.sc-rp-day-slot{background:var(--rp-color-highlight-soft);border-style:solid;border-color:var(--rp-color-highlight);box-shadow:var(--rp-shadow-md), inset 0 0 0 1px var(--rp-color-highlight)}.head.sc-rp-day-slot{display:flex;gap:var(--rp-space-2);align-items:center;justify-content:space-between;padding:var(--rp-space-3);border-bottom:1px solid var(--rp-color-border)}.day.sc-rp-day-slot{min-width:0;margin:0;overflow:hidden;font-size:var(--rp-font-size-xs);font-weight:700;letter-spacing:0.08em;text-transform:uppercase;text-overflow:ellipsis;white-space:nowrap;color:var(--rp-color-text-muted)}.head-right.sc-rp-day-slot{display:flex;flex-shrink:0;gap:var(--rp-space-2);align-items:center}.count.sc-rp-day-slot{display:grid;place-items:center;min-width:20px;height:20px;padding:0 6px;font-size:0.6875rem;font-weight:700;font-variant-numeric:tabular-nums;color:var(--rp-caramel-600);background:var(--rp-color-highlight-soft);border-radius:var(--rp-radius-pill)}.add.sc-rp-day-slot{display:grid;place-items:center;width:26px;height:26px;padding:0;cursor:pointer;color:var(--rp-color-accent-contrast);background:var(--rp-color-accent);border:none;border-radius:50%;transition:transform var(--rp-duration-fast) var(--rp-ease), background-color var(--rp-duration-fast) var(--rp-ease)}.add.sc-rp-day-slot svg.sc-rp-day-slot{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}.add.sc-rp-day-slot:hover{background:var(--rp-color-highlight);transform:rotate(90deg) scale(1.1)}.add.sc-rp-day-slot:active{transform:rotate(90deg) scale(0.92)}.meals.sc-rp-day-slot{flex:1;margin:0;padding:var(--rp-space-2);list-style:none;display:flex;flex-direction:column;gap:var(--rp-space-2)}.meal.sc-rp-day-slot{position:relative;padding:var(--rp-space-3) var(--rp-space-3) var(--rp-space-2);cursor:grab;background:var(--rp-color-surface-sunken);border:1px solid var(--rp-color-border);border-radius:var(--rp-radius-md);transition:transform var(--rp-duration-fast) var(--rp-ease), box-shadow var(--rp-duration-fast) var(--rp-ease), opacity var(--rp-duration-fast) var(--rp-ease)}.meal.sc-rp-day-slot:hover{background:var(--rp-color-surface);box-shadow:var(--rp-shadow-sm);transform:translateY(-1px)}.meal.sc-rp-day-slot:active{cursor:grabbing}.meal.is-dragging.sc-rp-day-slot{opacity:0.4;box-shadow:none;transform:none}.grip.sc-rp-day-slot{position:absolute;inset-block-start:var(--rp-space-2);inset-inline-end:var(--rp-space-2);display:block;opacity:0;transition:opacity var(--rp-duration-fast) var(--rp-ease)}.grip.sc-rp-day-slot svg.sc-rp-day-slot{display:block;fill:var(--rp-color-text-subtle)}.meal.sc-rp-day-slot:hover .grip.sc-rp-day-slot{opacity:1}.meal-title.sc-rp-day-slot{display:block;padding-inline-end:var(--rp-space-4);font-size:var(--rp-font-size-sm);font-weight:500;line-height:1.35;color:var(--rp-color-text)}.meal-actions.sc-rp-day-slot{display:flex;gap:var(--rp-space-1);align-items:center;justify-content:space-between;margin-top:var(--rp-space-2)}.move-select.sc-rp-day-slot{max-width:100%;padding:3px var(--rp-space-2);font:inherit;font-size:var(--rp-font-size-xs);color:var(--rp-color-text-muted);cursor:pointer;background:var(--rp-color-surface);border:1px solid var(--rp-color-border);border-radius:var(--rp-radius-sm);transition:border-color var(--rp-duration-fast) var(--rp-ease)}.move-select.sc-rp-day-slot:hover{border-color:var(--rp-color-border-strong)}.remove.sc-rp-day-slot{display:grid;place-items:center;width:24px;height:24px;padding:0;color:var(--rp-color-text-subtle);cursor:pointer;background:none;border:none;border-radius:var(--rp-radius-sm);transition:color var(--rp-duration-fast) var(--rp-ease), background-color var(--rp-duration-fast) var(--rp-ease)}.remove.sc-rp-day-slot svg.sc-rp-day-slot{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}.remove.sc-rp-day-slot:hover{color:var(--rp-color-danger);background:var(--rp-color-danger-soft)}.empty.sc-rp-day-slot{display:flex;flex:1;flex-direction:column;gap:var(--rp-space-2);align-items:center;justify-content:center;padding:var(--rp-space-4) var(--rp-space-3);text-align:center}.empty-icon.sc-rp-day-slot{fill:none;stroke:var(--rp-color-text-subtle);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}.empty-text.sc-rp-day-slot{margin:0;font-size:var(--rp-font-size-xs);color:var(--rp-color-text-subtle)}.add.sc-rp-day-slot:focus-visible,.remove.sc-rp-day-slot:focus-visible,.move-select.sc-rp-day-slot:focus-visible{outline:var(--rp-focus-ring);outline-offset:var(--rp-focus-offset)}.sr-only.sc-rp-day-slot{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@media (prefers-reduced-motion: reduce){.slot.sc-rp-day-slot,.meal.sc-rp-day-slot,.add.sc-rp-day-slot,.grip.sc-rp-day-slot,.remove.sc-rp-day-slot,.move-select.sc-rp-day-slot{transition:none}.meal.sc-rp-day-slot:hover,.add.sc-rp-day-slot:hover,.add.sc-rp-day-slot:active{transform:none}.grip.sc-rp-day-slot{opacity:1}}`;
|
|
6
6
|
|
|
7
7
|
const DaySlot = class {
|
|
8
8
|
constructor(hostRef) {
|
|
@@ -27,11 +27,20 @@ const DaySlot = class {
|
|
|
27
27
|
*/
|
|
28
28
|
dayLabels = {};
|
|
29
29
|
normalized = [];
|
|
30
|
+
/** True while a compatible meal is being dragged over this column. */
|
|
31
|
+
dropActive = false;
|
|
32
|
+
/** Id of the meal being dragged out of this column, dimmed at its origin. */
|
|
33
|
+
draggingId = null;
|
|
34
|
+
/**
|
|
35
|
+
* Nested children fire dragleave as the pointer crosses them, so a boolean flag would
|
|
36
|
+
* flicker off mid-column. Counting enter and leave pairs is what makes the state stable.
|
|
37
|
+
*/
|
|
38
|
+
dragDepth = 0;
|
|
30
39
|
/** Fired when the user asks to add a meal to this day. */
|
|
31
40
|
rpAddMeal;
|
|
32
41
|
/** Fired when a meal is removed from this day. */
|
|
33
42
|
rpRemoveMeal;
|
|
34
|
-
/** Fired when a meal is reassigned to a different day. */
|
|
43
|
+
/** Fired when a meal is reassigned to a different day, by drag or by select. */
|
|
35
44
|
rpMoveMeal;
|
|
36
45
|
componentWillLoad() {
|
|
37
46
|
this.normalized = Array.isArray(this.meals) ? this.meals : [];
|
|
@@ -41,23 +50,82 @@ const DaySlot = class {
|
|
|
41
50
|
// replaced before the element upgrades, which @Watch would miss.
|
|
42
51
|
this.normalized = Array.isArray(this.meals) ? this.meals : [];
|
|
43
52
|
}
|
|
53
|
+
emitMove(id, from, to) {
|
|
54
|
+
if (!to || to === from)
|
|
55
|
+
return;
|
|
56
|
+
this.rpMoveMeal.emit({ id, from, to });
|
|
57
|
+
}
|
|
44
58
|
onMove = (event, meal) => {
|
|
45
59
|
const select = event.target;
|
|
46
|
-
|
|
47
|
-
if (!to || to === this.day)
|
|
48
|
-
return;
|
|
49
|
-
this.rpMoveMeal.emit({ id: meal.id, from: this.day, to });
|
|
60
|
+
this.emitMove(meal.id, this.day, select.value);
|
|
50
61
|
// The consumer re-renders from its own data; resetting avoids a stale selection
|
|
51
62
|
// if that render is delayed.
|
|
52
63
|
select.value = '';
|
|
53
64
|
};
|
|
65
|
+
onDragStart = (event, meal) => {
|
|
66
|
+
this.draggingId = meal.id;
|
|
67
|
+
// A custom MIME type is what lets dragover distinguish a meal from a dragged file or
|
|
68
|
+
// a text selection, so unrelated drags never light up a column as a drop target.
|
|
69
|
+
event.dataTransfer?.setData('application/x-rp-meal', JSON.stringify({ id: meal.id, from: this.day }));
|
|
70
|
+
// text/plain is set alongside it because some browsers refuse a drag with no
|
|
71
|
+
// conventional format attached.
|
|
72
|
+
event.dataTransfer?.setData('text/plain', meal.title);
|
|
73
|
+
if (event.dataTransfer)
|
|
74
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
75
|
+
};
|
|
76
|
+
onDragEnd = () => {
|
|
77
|
+
this.draggingId = null;
|
|
78
|
+
this.dragDepth = 0;
|
|
79
|
+
this.dropActive = false;
|
|
80
|
+
};
|
|
81
|
+
hasMealPayload(event) {
|
|
82
|
+
return event.dataTransfer?.types.includes('application/x-rp-meal') ?? false;
|
|
83
|
+
}
|
|
84
|
+
onDragEnter = (event) => {
|
|
85
|
+
if (!this.hasMealPayload(event))
|
|
86
|
+
return;
|
|
87
|
+
this.dragDepth += 1;
|
|
88
|
+
this.dropActive = true;
|
|
89
|
+
};
|
|
90
|
+
onDragOver = (event) => {
|
|
91
|
+
if (!this.hasMealPayload(event))
|
|
92
|
+
return;
|
|
93
|
+
// Without preventDefault the browser treats the element as a non-drop zone and the
|
|
94
|
+
// drop event never fires.
|
|
95
|
+
event.preventDefault();
|
|
96
|
+
if (event.dataTransfer)
|
|
97
|
+
event.dataTransfer.dropEffect = 'move';
|
|
98
|
+
};
|
|
99
|
+
onDragLeave = (event) => {
|
|
100
|
+
if (!this.hasMealPayload(event))
|
|
101
|
+
return;
|
|
102
|
+
this.dragDepth = Math.max(0, this.dragDepth - 1);
|
|
103
|
+
if (this.dragDepth === 0)
|
|
104
|
+
this.dropActive = false;
|
|
105
|
+
};
|
|
106
|
+
onDrop = (event) => {
|
|
107
|
+
const payload = event.dataTransfer?.getData('application/x-rp-meal');
|
|
108
|
+
if (!payload)
|
|
109
|
+
return;
|
|
110
|
+
event.preventDefault();
|
|
111
|
+
this.dragDepth = 0;
|
|
112
|
+
this.dropActive = false;
|
|
113
|
+
try {
|
|
114
|
+
const { id, from } = JSON.parse(payload);
|
|
115
|
+
this.emitMove(id, from, this.day);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// A malformed payload means the drag did not originate here; ignoring it is
|
|
119
|
+
// preferable to throwing inside a drop handler, where nothing would catch it.
|
|
120
|
+
}
|
|
121
|
+
};
|
|
54
122
|
render() {
|
|
55
123
|
const days = Array.isArray(this.days) ? this.days : [];
|
|
56
124
|
const labels = this.dayLabels ?? {};
|
|
57
125
|
const meals = this.normalized;
|
|
58
|
-
return (index.h(index.Host, { key: '
|
|
126
|
+
return (index.h(index.Host, { key: '755cdc190abccb9b0350caf7e4fad05675dd6e0e' }, index.h("section", { key: '927c1e962ce3f918e001965da10bb39b82cab5bc', class: { slot: true, 'is-drop-active': this.dropActive, 'is-empty': meals.length === 0 }, onDragEnter: this.onDragEnter, onDragOver: this.onDragOver, onDragLeave: this.onDragLeave, onDrop: this.onDrop }, index.h("header", { key: '415e9d56f9b190fd291af942c01427cc4b9b66ea', class: "head" }, index.h("h3", { key: 'd0f20de86c70d85da545ec9ec9c57790961b78f0', class: "day" }, this.dayLabel || this.day), index.h("div", { key: '484a1e743a3f251865288f345ead14d87741ff8e', class: "head-right" }, meals.length > 0 && index.h("span", { key: 'ac3324168f0061f4bb173090e21c4b6f2334a168', class: "count" }, meals.length), index.h("button", { key: '5ca123821d1b90cc822bb3036884ce93f8cae19c', type: "button", class: "add", onClick: () => this.rpAddMeal.emit(this.day), "aria-label": `Add a meal to ${this.dayLabel || this.day}` }, index.h("svg", { key: 'e7b09c139cfd3106a83481a1bbb48bf99e82d47c', viewBox: "0 0 24 24", width: "15", height: "15", "aria-hidden": "true" }, index.h("path", { key: '06c62bb2b09a4c0676977411644d15d4217361a8', d: "M12 5v14M5 12h14" }))))), meals.length === 0 ? (index.h("div", { class: "empty" }, index.h("slot", null, index.h("svg", { class: "empty-icon", viewBox: "0 0 24 24", width: "26", height: "26", "aria-hidden": "true" }, index.h("path", { d: "M4 4h16v16H4z", opacity: "0.35" }), index.h("path", { d: "M8 2v4M16 2v4M4 10h16" })), index.h("p", { class: "empty-text" }, "No meals planned")))) : (index.h("ul", { class: "meals" }, meals.map((meal) => (index.h("li", { class: { meal: true, 'is-dragging': this.draggingId === meal.id }, key: meal.id, draggable: true, onDragStart: (event) => this.onDragStart(event, meal), onDragEnd: this.onDragEnd }, index.h("span", { class: "grip", "aria-hidden": "true" }, index.h("svg", { viewBox: "0 0 24 24", width: "12", height: "12" }, index.h("circle", { cx: "9", cy: "6", r: "1.4" }), index.h("circle", { cx: "15", cy: "6", r: "1.4" }), index.h("circle", { cx: "9", cy: "12", r: "1.4" }), index.h("circle", { cx: "15", cy: "12", r: "1.4" }), index.h("circle", { cx: "9", cy: "18", r: "1.4" }), index.h("circle", { cx: "15", cy: "18", r: "1.4" }))), index.h("span", { class: "meal-title" }, meal.title), index.h("div", { class: "meal-actions" }, index.h("label", { class: "move" }, index.h("span", { class: "sr-only" }, `Move ${meal.title} to another day`), index.h("select", { class: "move-select", onChange: (event) => this.onMove(event, meal) }, index.h("option", { value: "" }, "Move\u2026"), days
|
|
59
127
|
.filter((day) => day !== this.day)
|
|
60
|
-
.map((day) => (index.h("option", { key: day, value: day }, labels[day] ?? day))))), index.h("button", { type: "button", class: "remove", onClick: () => this.rpRemoveMeal.emit({ id: meal.id, day: this.day }), "aria-label": `Remove ${meal.title}` }, "
|
|
128
|
+
.map((day) => (index.h("option", { key: day, value: day }, labels[day] ?? day))))), index.h("button", { type: "button", class: "remove", onClick: () => this.rpRemoveMeal.emit({ id: meal.id, day: this.day }), "aria-label": `Remove ${meal.title}` }, index.h("svg", { viewBox: "0 0 24 24", width: "13", height: "13", "aria-hidden": "true" }, index.h("path", { d: "M6 6l12 12M18 6L6 18" }))))))))))));
|
|
61
129
|
}
|
|
62
130
|
};
|
|
63
131
|
DaySlot.style = rpDaySlotCss();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-CrJlwqe_.js');
|
|
4
4
|
|
|
5
|
-
const rpFilterChipsCss = () => `.sc-rp-filter-chips-h{display:block;font-family:var(--rp-font-sans)}.chips.sc-rp-filter-chips{display:flex;flex-wrap:wrap;gap:var(--rp-space-2)}.chip.sc-rp-filter-chips{padding:
|
|
5
|
+
const rpFilterChipsCss = () => `.sc-rp-filter-chips-h{display:block;font-family:var(--rp-font-sans)}.chips.sc-rp-filter-chips{display:flex;flex-wrap:wrap;gap:var(--rp-space-2)}.chip.sc-rp-filter-chips{padding:6px var(--rp-space-4);font:inherit;font-size:var(--rp-font-size-sm);font-weight:500;color:var(--rp-color-text-body);cursor:pointer;background:var(--rp-color-surface);border:1px solid var(--rp-color-border);border-radius:var(--rp-radius-pill);transition:color var(--rp-duration-fast) var(--rp-ease), background-color var(--rp-duration-fast) var(--rp-ease), border-color var(--rp-duration-fast) var(--rp-ease), transform var(--rp-duration-fast) var(--rp-ease), box-shadow var(--rp-duration-fast) var(--rp-ease)}.chip.sc-rp-filter-chips:hover{color:var(--rp-color-text);background:var(--rp-color-surface-sunken);border-color:var(--rp-color-border-strong);transform:translateY(-1px)}.chip.sc-rp-filter-chips:active{transform:translateY(0) scale(0.97)}.chip.is-selected.sc-rp-filter-chips{color:var(--rp-color-accent-contrast);background:var(--rp-color-accent);border-color:var(--rp-color-accent);box-shadow:var(--rp-shadow-sm)}.chip.is-selected.sc-rp-filter-chips:hover{color:var(--rp-color-accent-contrast);background:var(--rp-color-accent-hover);border-color:var(--rp-color-accent-hover)}.chip.sc-rp-filter-chips:focus-visible{outline:var(--rp-focus-ring);outline-offset:var(--rp-focus-offset)}@media (prefers-reduced-motion: reduce){.chip.sc-rp-filter-chips{transition:none}.chip.sc-rp-filter-chips:hover,.chip.sc-rp-filter-chips:active{transform:none}}`;
|
|
6
6
|
|
|
7
7
|
const FilterChips = class {
|
|
8
8
|
constructor(hostRef) {
|
|
@@ -29,12 +29,12 @@ const FilterChips = class {
|
|
|
29
29
|
// A string prop arriving from an HTML attribute would be unusable; tolerate it so
|
|
30
30
|
// the component behaves predictably in a plain .html page.
|
|
31
31
|
const options = Array.isArray(this.options) ? this.options : [];
|
|
32
|
-
return (index.h(index.Host, { key: '
|
|
32
|
+
return (index.h(index.Host, { key: 'f695ec8ae5603061f1fcf027257563c416f8fde8' }, index.h("div", { key: '80b59e2aaedd649ec387534da5dd3dc5d9955be5', class: "chips", role: "group", "aria-label": this.label }, options.map((option) => (index.h("button", { key: option, type: "button", class: { chip: true, 'is-selected': this.selected === option }, "aria-pressed": String(this.selected === option), onClick: () => this.select(option) }, option))))));
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
FilterChips.style = rpFilterChipsCss();
|
|
36
36
|
|
|
37
|
-
const rpIngredientListCss = () => `.sc-rp-ingredient-list-h{display:block;font-family:var(--rp-font-sans);color:var(--rp-color-text)}.heading.sc-rp-ingredient-list{margin:0 0 var(--rp-space-
|
|
37
|
+
const rpIngredientListCss = () => `.sc-rp-ingredient-list-h{display:block;font-family:var(--rp-font-sans);color:var(--rp-color-text)}.heading.sc-rp-ingredient-list{margin:0 0 var(--rp-space-4);font-family:var(--rp-font-serif);font-size:var(--rp-font-size-xl);font-weight:600;letter-spacing:-0.015em}.list.sc-rp-ingredient-list{margin:0;padding:var(--rp-space-2);list-style:none;background:var(--rp-color-surface);border:1px solid var(--rp-color-border);border-radius:var(--rp-radius-lg);box-shadow:var(--rp-shadow-xs);overflow:hidden}.row.sc-rp-ingredient-list{display:flex;justify-content:space-between;gap:var(--rp-space-4);padding:var(--rp-space-3);font-size:var(--rp-font-size-md);border-radius:var(--rp-radius-sm);transition:background-color var(--rp-duration-fast) var(--rp-ease)}.row.sc-rp-ingredient-list:hover{background:var(--rp-color-highlight-soft)}.name.sc-rp-ingredient-list{color:var(--rp-color-text-body)}.measure.sc-rp-ingredient-list{flex-shrink:0;font-size:var(--rp-font-size-sm);font-weight:600;color:var(--rp-caramel-600);font-variant-numeric:tabular-nums}.empty.sc-rp-ingredient-list{margin:0;padding:var(--rp-space-5);font-size:var(--rp-font-size-md);color:var(--rp-color-text-muted);text-align:center;background:var(--rp-color-surface-sunken);border:1px dashed var(--rp-color-border-strong);border-radius:var(--rp-radius-lg)}.note.sc-rp-ingredient-list{margin-top:var(--rp-space-3);font-size:var(--rp-font-size-sm);color:var(--rp-color-text-muted);text-align:center}.note.sc-rp-ingredient-list:not(:has(*)){display:none}@media (prefers-reduced-motion: reduce){.row.sc-rp-ingredient-list{transition:none}}`;
|
|
38
38
|
|
|
39
39
|
const IngredientList = class {
|
|
40
40
|
constructor(hostRef) {
|
|
@@ -44,15 +44,15 @@ const IngredientList = class {
|
|
|
44
44
|
items = [];
|
|
45
45
|
render() {
|
|
46
46
|
const items = Array.isArray(this.items) ? this.items : [];
|
|
47
|
-
return (index.h(index.Host, { key: '
|
|
47
|
+
return (index.h(index.Host, { key: '125fe2f063e9b5a816d815a8541375e424e68be6' }, index.h("section", { key: 'fcde8050442e5b8a49636ff38b9db7e3585b5290', class: "wrap" }, index.h("slot", { key: 'db3a3d738036b8e7292cdd2202b98f665b2b98fd', name: "heading" }, index.h("h2", { key: '256a5cf73cc89b3674b1ff421fa1acbaa4b0bf9a', class: "heading" }, "Ingredients")), items.length === 0 ? (index.h("p", { class: "empty" }, "No ingredients listed for this recipe.")) : (index.h("ul", { class: "list" }, items.map((item, index$1) => (
|
|
48
48
|
// Ingredient names repeat within a recipe (for example, oil listed twice
|
|
49
49
|
// with different measures), so the index is part of the identity.
|
|
50
|
-
index.h("li", { class: "row", key: `${item.name}-${index$1}` }, index.h("span", { class: "name" }, item.name), index.h("span", { class: "measure" }, item.measure)))))), index.h("div", { key: '
|
|
50
|
+
index.h("li", { class: "row", key: `${item.name}-${index$1}` }, index.h("span", { class: "name" }, item.name), index.h("span", { class: "measure" }, item.measure)))))), index.h("div", { key: '1885bcef40eb856cb331f0cca95f6b2e5a044f3c', class: "note" }, index.h("slot", { key: '2381d91aeb01f0e67adb12fc417f6964432f5e06' })))));
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
IngredientList.style = rpIngredientListCss();
|
|
54
54
|
|
|
55
|
-
const rpModalCss = () => `.sc-rp-modal-h{display:contents;font-family:var(--rp-font-sans)}.backdrop.sc-rp-modal{position:fixed;inset:0;z-index:100;display:grid;place-items:center;padding:var(--rp-space-4);background:rgb(
|
|
55
|
+
const rpModalCss = () => `.sc-rp-modal-h{display:contents;font-family:var(--rp-font-sans)}.sc-rp-modal-h:not([open]){display:none}.backdrop.sc-rp-modal{position:fixed;inset:0;z-index:100;display:grid;place-items:center;padding:var(--rp-space-4);background:rgb(44 24 16 / 0.42);backdrop-filter:blur(6px)}.dialog.sc-rp-modal{display:flex;flex-direction:column;width:min(560px, 100%);max-height:min(80vh, 640px);overflow:hidden;color:var(--rp-color-text);background:var(--rp-color-surface);border:1px solid var(--rp-color-border);border-radius:var(--rp-radius-xl);box-shadow:var(--rp-shadow-xl)}.head.sc-rp-modal{display:flex;gap:var(--rp-space-3);align-items:center;justify-content:space-between;padding:var(--rp-space-5) var(--rp-space-5) var(--rp-space-4);border-bottom:1px solid var(--rp-color-border)}.heading.sc-rp-modal{margin:0;font-family:var(--rp-font-serif);font-size:var(--rp-font-size-xl);font-weight:600;letter-spacing:-0.015em}.close.sc-rp-modal{display:grid;place-items:center;flex-shrink:0;width:32px;height:32px;padding:0;color:var(--rp-color-text-muted);cursor:pointer;background:none;border:none;border-radius:50%;transition:color var(--rp-duration-fast) var(--rp-ease), background-color var(--rp-duration-fast) var(--rp-ease), transform var(--rp-duration-fast) var(--rp-ease)}.close.sc-rp-modal svg.sc-rp-modal{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}.close.sc-rp-modal:hover{color:var(--rp-color-text);background:var(--rp-color-surface-sunken);transform:rotate(90deg)}.close.sc-rp-modal:focus-visible{outline:var(--rp-focus-ring);outline-offset:var(--rp-focus-offset)}.body.sc-rp-modal{flex:1;padding:var(--rp-space-5);font-size:var(--rp-font-size-md);color:var(--rp-color-text-body);overflow-y:auto}.foot.sc-rp-modal{display:flex;gap:var(--rp-space-2);justify-content:flex-end;padding:var(--rp-space-4) var(--rp-space-5) var(--rp-space-5);background:var(--rp-color-surface-sunken);border-top:1px solid var(--rp-color-border)}.foot.sc-rp-modal:not(:has(*)){display:none}@media (prefers-reduced-motion: no-preference){.backdrop.sc-rp-modal{animation:rp-backdrop-in var(--rp-duration) var(--rp-ease)}.dialog.sc-rp-modal{animation:rp-modal-in var(--rp-duration) var(--rp-ease)}@keyframes rp-backdrop-in{from{opacity:0}}@keyframes rp-modal-in{from{opacity:0;transform:translateY(12px) scale(0.97)}}}@media (prefers-reduced-motion: reduce){.close.sc-rp-modal{transition:none}.close.sc-rp-modal:hover{transform:none}}`;
|
|
56
56
|
|
|
57
57
|
const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
58
58
|
const Modal = class {
|
|
@@ -135,7 +135,7 @@ const Modal = class {
|
|
|
135
135
|
render() {
|
|
136
136
|
if (!this.open)
|
|
137
137
|
return null;
|
|
138
|
-
return (index.h(index.Host, null, index.h("div", { class: "backdrop", onClick: this.onBackdropClick }, index.h("div", { class: "dialog", role: "dialog", "aria-modal": "true", "aria-label": this.heading }, index.h("header", { class: "head" }, index.h("h2", { class: "heading" }, this.heading), index.h("button", { type: "button", class: "close", onClick: () => this.rpClose.emit(), "aria-label": "Close dialog" }, "
|
|
138
|
+
return (index.h(index.Host, null, index.h("div", { class: "backdrop", onClick: this.onBackdropClick }, index.h("div", { class: "dialog", role: "dialog", "aria-modal": "true", "aria-label": this.heading }, index.h("header", { class: "head" }, index.h("h2", { class: "heading" }, this.heading), index.h("button", { type: "button", class: "close", onClick: () => this.rpClose.emit(), "aria-label": "Close dialog" }, index.h("svg", { viewBox: "0 0 24 24", width: "15", height: "15", "aria-hidden": "true" }, index.h("path", { d: "M6 6l12 12M18 6L6 18" })))), index.h("div", { class: "body" }, index.h("slot", null)), index.h("footer", { class: "foot" }, index.h("slot", { name: "footer" }))))));
|
|
139
139
|
}
|
|
140
140
|
static get watchers() { return {
|
|
141
141
|
"open": [{
|
|
@@ -145,7 +145,7 @@ const Modal = class {
|
|
|
145
145
|
};
|
|
146
146
|
Modal.style = rpModalCss();
|
|
147
147
|
|
|
148
|
-
const rpRecipeCardCss = () => `.sc-rp-recipe-card-h{display:block;font-family:var(--rp-font-sans);color:var(--rp-color-text)}.card.sc-rp-recipe-card{display:flex;flex-direction:column;height:100%;overflow:hidden;background:var(--rp-color-surface);border:1px solid var(--rp-color-border);border-radius:var(--rp-radius-lg);box-shadow:var(--rp-shadow-sm)}.media.sc-rp-recipe-card{position:relative;aspect-ratio:4 / 3;background:var(--rp-color-surface-sunken)}.media.sc-rp-recipe-card img.sc-rp-recipe-card{display:block;width:100%;height:100%;object-fit:cover}.media-fallback.sc-rp-recipe-card{width:100%;height:100%;background:linear-gradient(135deg, var(--rp-
|
|
148
|
+
const rpRecipeCardCss = () => `.sc-rp-recipe-card-h{display:block;font-family:var(--rp-font-sans);color:var(--rp-color-text)}.card.sc-rp-recipe-card{display:flex;flex-direction:column;height:100%;overflow:hidden;background:var(--rp-color-surface);border:1px solid var(--rp-color-border);border-radius:var(--rp-radius-lg);box-shadow:var(--rp-shadow-sm);transition:transform var(--rp-duration) var(--rp-ease), box-shadow var(--rp-duration) var(--rp-ease), border-color var(--rp-duration) var(--rp-ease)}.sc-rp-recipe-card-h:hover .card.sc-rp-recipe-card{border-color:var(--rp-color-border-strong);box-shadow:var(--rp-shadow-lg);transform:translateY(-4px)}.media.sc-rp-recipe-card{position:relative;aspect-ratio:4 / 3;overflow:hidden;background:var(--rp-color-surface-sunken)}.media.sc-rp-recipe-card img.sc-rp-recipe-card{display:block;width:100%;height:100%;object-fit:cover;transition:transform var(--rp-duration-slow) var(--rp-ease), opacity var(--rp-duration) var(--rp-ease)}.sc-rp-recipe-card-h:hover .media.sc-rp-recipe-card img.sc-rp-recipe-card{transform:scale(1.04)}.media.is-loading.sc-rp-recipe-card img.sc-rp-recipe-card{opacity:0}.media-fallback.sc-rp-recipe-card{width:100%;height:100%;background:radial-gradient(circle at 30% 25%, rgb(255 255 255 / 0.55), transparent 55%), linear-gradient(135deg, var(--rp-caramel-100), var(--rp-cream-400))}.scrim.sc-rp-recipe-card{position:absolute;inset:0;pointer-events:none;background:linear-gradient(to bottom, rgb(44 24 16 / 0.18) 0%, transparent 34%)}.badges.sc-rp-recipe-card{position:absolute;inset-block-start:var(--rp-space-3);inset-inline-start:var(--rp-space-3);display:flex;flex-wrap:wrap;gap:var(--rp-space-1)}.favorite.sc-rp-recipe-card{position:absolute;inset-block-start:var(--rp-space-3);inset-inline-end:var(--rp-space-3);display:grid;place-items:center;width:36px;height:36px;padding:0;cursor:pointer;background:rgb(255 255 255 / 0.82);backdrop-filter:blur(8px);border:1px solid rgb(255 255 255 / 0.6);border-radius:50%;box-shadow:var(--rp-shadow-sm);transition:transform var(--rp-duration-fast) var(--rp-ease), background-color var(--rp-duration-fast) var(--rp-ease)}.favorite.sc-rp-recipe-card:hover{background:var(--rp-color-surface);transform:scale(1.08)}.favorite.sc-rp-recipe-card:active{transform:scale(0.94)}.favorite.sc-rp-recipe-card svg.sc-rp-recipe-card{fill:none;stroke:var(--rp-espresso-800);stroke-width:1.9;stroke-linejoin:round;transition:fill var(--rp-duration-fast) var(--rp-ease), stroke var(--rp-duration-fast) var(--rp-ease)}[favorite].sc-rp-recipe-card-h .favorite.sc-rp-recipe-card svg.sc-rp-recipe-card{fill:var(--rp-color-favorite);stroke:var(--rp-color-favorite-strong)}[favorite].sc-rp-recipe-card-h .favorite.sc-rp-recipe-card:hover svg.sc-rp-recipe-card{fill:var(--rp-color-favorite-strong)}.favorite.sc-rp-recipe-card:focus-visible{outline:var(--rp-focus-ring);outline-offset:var(--rp-focus-offset)}.body.sc-rp-recipe-card{flex:1;padding:var(--rp-space-4) var(--rp-space-4) var(--rp-space-3)}.title.sc-rp-recipe-card{margin:0;font-family:var(--rp-font-serif);font-size:1.0625rem;font-weight:600;line-height:1.28;letter-spacing:-0.01em;color:var(--rp-color-text);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden}.meta.sc-rp-recipe-card{display:flex;flex-wrap:wrap;gap:var(--rp-space-1);margin-top:var(--rp-space-3)}.pill.sc-rp-recipe-card{padding:3px 10px;font-size:var(--rp-font-size-xs);font-weight:500;letter-spacing:0.01em;color:var(--rp-color-text-muted);background:var(--rp-color-surface-sunken);border:1px solid var(--rp-color-border);border-radius:var(--rp-radius-pill);white-space:nowrap}.pill-category.sc-rp-recipe-card{color:var(--rp-caramel-600);background:var(--rp-color-highlight-soft);border-color:transparent}.actions.sc-rp-recipe-card{display:flex;gap:var(--rp-space-3);align-items:center;padding:0 var(--rp-space-4) var(--rp-space-4)}.actions.sc-rp-recipe-card:not(:has(*)){display:none}@media (prefers-reduced-motion: no-preference){.media.is-loading.sc-rp-recipe-card::after{content:'';position:absolute;inset:0;background:linear-gradient( 100deg, transparent 20%, rgb(255 255 255 / 0.7) 50%, transparent 80% );background-size:220% 100%;animation:rp-card-shimmer 1.6s var(--rp-ease) infinite}@keyframes rp-card-shimmer{from{background-position:180% 0}to{background-position:-80% 0}}.favorite.is-pulsing.sc-rp-recipe-card{animation:rp-favorite-pop 400ms var(--rp-ease)}@keyframes rp-favorite-pop{0%{transform:scale(1)}35%{transform:scale(0.86)}70%{transform:scale(1.16)}100%{transform:scale(1)}}.favorite.is-pulsing.sc-rp-recipe-card svg.sc-rp-recipe-card{animation:rp-heart-beat 400ms var(--rp-ease);transform-origin:center}@keyframes rp-heart-beat{0%{transform:scale(1)}30%{transform:scale(0.7)}55%{transform:scale(1.35)}75%{transform:scale(0.94)}100%{transform:scale(1)}}}@media (prefers-reduced-motion: reduce){.card.sc-rp-recipe-card,.media.sc-rp-recipe-card img.sc-rp-recipe-card,.favorite.sc-rp-recipe-card{transition:none}.sc-rp-recipe-card-h:hover .card.sc-rp-recipe-card{transform:none}.sc-rp-recipe-card-h:hover .media.sc-rp-recipe-card img.sc-rp-recipe-card{transform:none}.media.is-loading.sc-rp-recipe-card img.sc-rp-recipe-card{opacity:1}}`;
|
|
149
149
|
|
|
150
150
|
const RecipeCard = class {
|
|
151
151
|
constructor(hostRef) {
|
|
@@ -166,28 +166,59 @@ const RecipeCard = class {
|
|
|
166
166
|
image;
|
|
167
167
|
/** Category label shown under the heading. */
|
|
168
168
|
category;
|
|
169
|
+
/** Cuisine or region, shown as a second meta pill when present. */
|
|
170
|
+
area;
|
|
171
|
+
/** Preparation time in minutes, shown as a meta pill when present. */
|
|
172
|
+
minutes;
|
|
169
173
|
/** Whether this recipe is currently a favorite. Reflected for CSS hooks. */
|
|
170
174
|
favorite = false;
|
|
175
|
+
/**
|
|
176
|
+
* True between the image element being created and its load event.
|
|
177
|
+
*
|
|
178
|
+
* Drives the shimmer placeholder behind the image. Tracked in state rather than with a
|
|
179
|
+
* CSS-only trick because a cached image can complete before this component ever renders,
|
|
180
|
+
* and the load event would then never fire — `onLoad` plus the `complete` check in
|
|
181
|
+
* `onImageRef` covers both orderings.
|
|
182
|
+
*/
|
|
183
|
+
imageLoading = true;
|
|
184
|
+
/** Set when the image URL fails, so a broken link falls back to the gradient. */
|
|
185
|
+
imageFailed = false;
|
|
186
|
+
/** Briefly true after a favorite toggle, driving the press animation. */
|
|
187
|
+
pulsing = false;
|
|
188
|
+
pulseTimer;
|
|
171
189
|
/** Fired when the favorite control is activated. */
|
|
172
190
|
rpFavoriteToggle;
|
|
191
|
+
disconnectedCallback() {
|
|
192
|
+
clearTimeout(this.pulseTimer);
|
|
193
|
+
}
|
|
173
194
|
toggleFavorite = () => {
|
|
195
|
+
this.pulsing = true;
|
|
196
|
+
clearTimeout(this.pulseTimer);
|
|
197
|
+
this.pulseTimer = setTimeout(() => (this.pulsing = false), 400);
|
|
174
198
|
// Emits the intended next state. The consumer owns the data and decides whether
|
|
175
199
|
// the change is applied, so this component never writes to its own prop.
|
|
176
200
|
this.rpFavoriteToggle.emit({ recipeId: this.recipeId, favorite: !this.favorite });
|
|
177
201
|
};
|
|
202
|
+
onImageRef = (element) => {
|
|
203
|
+
// A browser-cached image is already complete by the time the ref runs, and its load
|
|
204
|
+
// event fired before the listener was attached.
|
|
205
|
+
if (element?.complete)
|
|
206
|
+
this.imageLoading = false;
|
|
207
|
+
};
|
|
178
208
|
render() {
|
|
179
209
|
// Normalized because a consumer that omits the attribute entirely leaves the prop
|
|
180
210
|
// undefined, and `aria-pressed="undefined"` would be dropped from the DOM, leaving a
|
|
181
211
|
// toggle button with no announced state.
|
|
182
212
|
const isFavorite = this.favorite === true;
|
|
183
|
-
|
|
213
|
+
const showImage = this.image && !this.imageFailed;
|
|
214
|
+
return (index.h(index.Host, { key: '0853c21cb52a51e3b65b3cb056681f9c3976755f' }, index.h("article", { key: 'cb237de486c7300a7767ce3d9ae3a36880db48ec', class: "card" }, index.h("div", { key: '8dae01d89747a1838f56f4ca6e4dbdb33ef5d20e', class: { media: true, 'is-loading': showImage && this.imageLoading } }, showImage ? (index.h("img", { src: this.image, alt: "", loading: "lazy", width: "320", height: "240", ref: this.onImageRef, onLoad: () => (this.imageLoading = false), onError: () => (this.imageFailed = true) })) : (index.h("div", { class: "media-fallback", "aria-hidden": "true" })), index.h("div", { key: '3d147214228cc28f084c290309b80debca6d07da', class: "scrim", "aria-hidden": "true" }), index.h("div", { key: '7855d08ff646493f9e5a18c8e0a72333c4f68712', class: "badges" }, index.h("slot", { key: '3b0ceeedd343856ccc0d2e4e2f64d74ef281e956' })), index.h("button", { key: 'ec3df3f7b5ce63ce3af39b0f084cdad1aab23c87', type: "button", class: { favorite: true, 'is-pulsing': this.pulsing }, onClick: this.toggleFavorite, "aria-pressed": isFavorite ? 'true' : 'false', "aria-label": isFavorite
|
|
184
215
|
? `Remove ${this.recipeTitle} from favorites`
|
|
185
|
-
: `Add ${this.recipeTitle} to favorites` }, index.h("svg", { key: '
|
|
216
|
+
: `Add ${this.recipeTitle} to favorites` }, index.h("svg", { key: '0b817dc9b6a13e7e6b775b0023e27f3058addadc', viewBox: "0 0 24 24", width: "18", height: "18", "aria-hidden": "true" }, index.h("path", { key: '3ae5280802bd9a503ab1d0991da56cdd81289607', d: "M12 21s-7.5-4.7-9.3-9A5.2 5.2 0 0 1 12 6.5 5.2 5.2 0 0 1 21.3 12c-1.8 4.3-9.3 9-9.3 9z" })))), index.h("div", { key: '631852cc8f9fd12f3af480fe77c9f9db210fb51e', class: "body" }, index.h("h3", { key: '334bd4822bbe8e81e98dd643b2e18945d5505c6f', class: "title" }, this.recipeTitle), index.h("div", { key: 'b91559eb5881354a9b20167b95a2be9892d4d9fb', class: "meta" }, this.category && index.h("span", { key: 'f993dfb8bf33257ee176773b6e1750bb6d938b5c', class: "pill pill-category" }, this.category), this.area && index.h("span", { key: '4af2e93af6c26e3dba6544d6f629f2b2fc21f78f', class: "pill" }, this.area), this.minutes ? index.h("span", { class: "pill" }, this.minutes, " min") : null)), index.h("div", { key: '3e05bc49f48af8e5112cc912018991ca9f3e8531', class: "actions" }, index.h("slot", { key: '948de8c02c3520b26134b93df0b460c659c3729f', name: "actions" })))));
|
|
186
217
|
}
|
|
187
218
|
};
|
|
188
219
|
RecipeCard.style = rpRecipeCardCss();
|
|
189
220
|
|
|
190
|
-
const rpSearchBarCss = () => `.sc-rp-search-bar-h{display:block;font-family:var(--rp-font-sans)}.bar.sc-rp-search-bar{display:flex;gap:var(--rp-space-2);align-items:center
|
|
221
|
+
const rpSearchBarCss = () => `.sc-rp-search-bar-h{display:block;font-family:var(--rp-font-sans)}.bar.sc-rp-search-bar{display:flex;gap:var(--rp-space-2);align-items:center;padding:5px 5px 5px var(--rp-space-4);background:var(--rp-color-surface);border:1px solid var(--rp-color-border);border-radius:var(--rp-radius-pill);box-shadow:var(--rp-shadow-sm);transition:border-color var(--rp-duration) var(--rp-ease), box-shadow var(--rp-duration) var(--rp-ease)}.bar.sc-rp-search-bar:hover{border-color:var(--rp-color-border-strong)}.bar.sc-rp-search-bar:focus-within{border-color:var(--rp-color-focus);box-shadow:var(--rp-shadow-sm), var(--rp-focus-halo)}.icon.sc-rp-search-bar{flex-shrink:0;fill:none;stroke:var(--rp-color-text-subtle);stroke-width:2;stroke-linecap:round;transition:stroke var(--rp-duration) var(--rp-ease)}.bar.sc-rp-search-bar:focus-within .icon.sc-rp-search-bar{stroke:var(--rp-color-focus)}.field.sc-rp-search-bar{flex:1;min-width:0;padding:var(--rp-space-2) 0;font:inherit;font-size:var(--rp-font-size-md);color:var(--rp-color-text);background:none;border:none}.field.sc-rp-search-bar::placeholder{color:var(--rp-color-text-subtle)}.field.sc-rp-search-bar:focus{outline:none}.field.sc-rp-search-bar::-webkit-search-cancel-button{display:none}.clear.sc-rp-search-bar{display:grid;place-items:center;width:30px;height:30px;padding:0;color:var(--rp-color-text-subtle);cursor:pointer;background:none;border:none;border-radius:50%;transition:color var(--rp-duration-fast) var(--rp-ease), background-color var(--rp-duration-fast) var(--rp-ease)}.clear.sc-rp-search-bar svg.sc-rp-search-bar{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}.clear.sc-rp-search-bar:hover{color:var(--rp-color-text);background:var(--rp-color-surface-sunken)}.submit.sc-rp-search-bar{flex-shrink:0;padding:var(--rp-space-2) var(--rp-space-5);font:inherit;font-size:var(--rp-font-size-md);font-weight:600;color:var(--rp-color-accent-contrast);cursor:pointer;background:var(--rp-color-accent);border:none;border-radius:var(--rp-radius-pill);transition:background-color var(--rp-duration-fast) var(--rp-ease), transform var(--rp-duration-fast) var(--rp-ease)}.submit.sc-rp-search-bar:hover{background:var(--rp-color-accent-hover)}.submit.sc-rp-search-bar:active{transform:scale(0.97)}.field.sc-rp-search-bar:focus-visible,.submit.sc-rp-search-bar:focus-visible,.clear.sc-rp-search-bar:focus-visible{outline:var(--rp-focus-ring);outline-offset:var(--rp-focus-offset)}@media (max-width: 480px){.submit.sc-rp-search-bar{padding-inline:var(--rp-space-4)}}@media (prefers-reduced-motion: reduce){.bar.sc-rp-search-bar,.icon.sc-rp-search-bar,.clear.sc-rp-search-bar,.submit.sc-rp-search-bar{transition:none}.submit.sc-rp-search-bar:active{transform:none}}`;
|
|
191
222
|
|
|
192
223
|
const SearchBar = class {
|
|
193
224
|
constructor(hostRef) {
|
|
@@ -229,7 +260,7 @@ const SearchBar = class {
|
|
|
229
260
|
this.rpClear.emit();
|
|
230
261
|
};
|
|
231
262
|
render() {
|
|
232
|
-
return (index.h(index.Host, { key: '
|
|
263
|
+
return (index.h(index.Host, { key: '958692b102c49ab9636a6cb8c9ae24244255cd45' }, index.h("form", { key: 'b5a9f510d1a7a7e0a3240716d46fad11eb0c274a', class: "bar", role: "search", onSubmit: this.onSubmit }, index.h("svg", { key: 'd0cf5b683a6e09f6353d83092aa268a0ac9d7927', class: "icon", viewBox: "0 0 24 24", width: "18", height: "18", "aria-hidden": "true" }, index.h("circle", { key: '5d20b9fffbc1b277476d1a525ecc5030483ba74a', cx: "11", cy: "11", r: "7" }), index.h("path", { key: '2619cf8d6701bb9fa8ad2e6dae48622ff90793c5', d: "m20 20-3.6-3.6" })), index.h("input", { key: '406028370f6179cb24253dda465531f465bd1f6e', type: "search", class: "field", value: this.draft, placeholder: this.placeholder, "aria-label": this.label, onInput: this.onInput }), this.draft && (index.h("button", { key: '5c0c3d9f0cc9635e91d78726f6da1c199bb10dad', type: "button", class: "clear", onClick: this.onClear, "aria-label": "Clear search" }, index.h("svg", { key: '83cdcaadfcca53df2fe73eff82d6bddbe3f81a6c', viewBox: "0 0 24 24", width: "14", height: "14", "aria-hidden": "true" }, index.h("path", { key: '89f434e831ec5410c83322b09cd4c570e941134f', d: "M6 6l12 12M18 6L6 18" })))), index.h("button", { key: '503500b25e4ea596ad33250ef46ce66c67d3e917', type: "submit", class: "submit" }, "Search"))));
|
|
233
264
|
}
|
|
234
265
|
static get watchers() { return {
|
|
235
266
|
"value": [{
|