recipe-planner-ui 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/LICENSE +21 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js +5 -0
- package/dist/cjs/index-B6uIqnrk.js +2043 -0
- package/dist/cjs/index.cjs.js +2 -0
- package/dist/cjs/loader.cjs.js +13 -0
- package/dist/cjs/recipe-planner-ui.cjs.js +25 -0
- package/dist/cjs/rp-day-slot.cjs.entry.js +57 -0
- package/dist/cjs/rp-filter-chips_5.cjs.entry.js +240 -0
- package/dist/collection/collection-manifest.json +18 -0
- package/dist/collection/components/rp-day-slot/rp-day-slot.css +131 -0
- package/dist/collection/components/rp-day-slot/rp-day-slot.js +201 -0
- package/dist/collection/components/rp-filter-chips/rp-filter-chips.css +36 -0
- package/dist/collection/components/rp-filter-chips/rp-filter-chips.js +123 -0
- package/dist/collection/components/rp-ingredient-list/rp-ingredient-list.css +53 -0
- package/dist/collection/components/rp-ingredient-list/rp-ingredient-list.js +57 -0
- package/dist/collection/components/rp-modal/rp-modal.css +94 -0
- package/dist/collection/components/rp-modal/rp-modal.js +196 -0
- package/dist/collection/components/rp-recipe-card/rp-recipe-card.css +106 -0
- package/dist/collection/components/rp-recipe-card/rp-recipe-card.js +170 -0
- package/dist/collection/components/rp-search-bar/rp-search-bar.css +65 -0
- package/dist/collection/components/rp-search-bar/rp-search-bar.js +166 -0
- package/dist/collection/index.js +1 -0
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +1 -0
- package/dist/components/rp-day-slot.d.ts +11 -0
- package/dist/components/rp-day-slot.js +1 -0
- package/dist/components/rp-filter-chips.d.ts +11 -0
- package/dist/components/rp-filter-chips.js +1 -0
- package/dist/components/rp-ingredient-list.d.ts +11 -0
- package/dist/components/rp-ingredient-list.js +1 -0
- package/dist/components/rp-modal.d.ts +11 -0
- package/dist/components/rp-modal.js +1 -0
- package/dist/components/rp-recipe-card.d.ts +11 -0
- package/dist/components/rp-recipe-card.js +1 -0
- package/dist/components/rp-search-bar.d.ts +11 -0
- package/dist/components/rp-search-bar.js +1 -0
- package/dist/esm/app-globals-DQuL1Twl.js +3 -0
- package/dist/esm/index-B4wAFfci.js +2034 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/loader.js +11 -0
- package/dist/esm/recipe-planner-ui.js +21 -0
- package/dist/esm/rp-day-slot.entry.js +55 -0
- package/dist/esm/rp-filter-chips_5.entry.js +234 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/recipe-planner-ui/index.esm.js +0 -0
- package/dist/recipe-planner-ui/p-66ba2983.entry.js +1 -0
- package/dist/recipe-planner-ui/p-B4wAFfci.js +3 -0
- package/dist/recipe-planner-ui/p-DQuL1Twl.js +1 -0
- package/dist/recipe-planner-ui/p-d54dbd37.entry.js +1 -0
- package/dist/recipe-planner-ui/recipe-planner-ui.css +1 -0
- package/dist/recipe-planner-ui/recipe-planner-ui.esm.js +1 -0
- package/dist/types/components/rp-day-slot/rp-day-slot.d.ts +41 -0
- package/dist/types/components/rp-filter-chips/rp-filter-chips.d.ts +24 -0
- package/dist/types/components/rp-ingredient-list/rp-ingredient-list.d.ts +14 -0
- package/dist/types/components/rp-modal/rp-modal.d.ts +34 -0
- package/dist/types/components/rp-recipe-card/rp-recipe-card.d.ts +36 -0
- package/dist/types/components/rp-search-bar/rp-search-bar.d.ts +31 -0
- package/dist/types/components.d.ts +536 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/stencil-public-runtime.d.ts +1873 -0
- package/loader/cdn.js +1 -0
- package/loader/index.cjs.js +1 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +1 -0
- package/loader/index.js +2 -0
- package/package.json +72 -0
- package/readme.md +131 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
|
+
/**
|
|
3
|
+
* A recipe summary tile.
|
|
4
|
+
*
|
|
5
|
+
* Takes only primitives, so it can be driven from plain HTML attributes with no
|
|
6
|
+
* framework present. It has no idea where a recipe comes from or what a route is —
|
|
7
|
+
* consumers inject navigation through the `actions` slot.
|
|
8
|
+
*
|
|
9
|
+
* @slot - Badges rendered over the image, such as a category or source marker.
|
|
10
|
+
* @slot actions - Controls rendered in the footer, typically links to view or edit.
|
|
11
|
+
*/
|
|
12
|
+
export declare class RecipeCard {
|
|
13
|
+
el: HTMLElement;
|
|
14
|
+
/** Identifier echoed back in the toggle event so consumers know which card fired. */
|
|
15
|
+
recipeId: string;
|
|
16
|
+
/**
|
|
17
|
+
* Recipe name, rendered as the card heading.
|
|
18
|
+
*
|
|
19
|
+
* Named `recipeTitle` rather than `title` because every HTMLElement already defines
|
|
20
|
+
* `title` on its prototype; shadowing it produces inconsistent behaviour across browsers.
|
|
21
|
+
*/
|
|
22
|
+
recipeTitle: string;
|
|
23
|
+
/** Absolute URL of the recipe image. */
|
|
24
|
+
image?: string;
|
|
25
|
+
/** Category label shown under the heading. */
|
|
26
|
+
category?: string;
|
|
27
|
+
/** Whether this recipe is currently a favorite. Reflected for CSS hooks. */
|
|
28
|
+
favorite: boolean;
|
|
29
|
+
/** Fired when the favorite control is activated. */
|
|
30
|
+
rpFavoriteToggle: EventEmitter<{
|
|
31
|
+
recipeId: string;
|
|
32
|
+
favorite: boolean;
|
|
33
|
+
}>;
|
|
34
|
+
private toggleFavorite;
|
|
35
|
+
render(): any;
|
|
36
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
|
+
/**
|
|
3
|
+
* A search input that emits on submit rather than on every keystroke.
|
|
4
|
+
*
|
|
5
|
+
* Per-keystroke events would race the consumer's own navigation: each one triggers a
|
|
6
|
+
* server round trip, and a slow response can land after the user has typed more,
|
|
7
|
+
* overwriting the field. Submitting explicitly keeps the interaction deterministic.
|
|
8
|
+
*/
|
|
9
|
+
export declare class SearchBar {
|
|
10
|
+
/** Initial query text. Changing it externally resets the field. */
|
|
11
|
+
value: string;
|
|
12
|
+
/** Placeholder shown when the field is empty. */
|
|
13
|
+
placeholder: string;
|
|
14
|
+
/** Accessible label for the input. */
|
|
15
|
+
label: string;
|
|
16
|
+
/**
|
|
17
|
+
* Live field contents. Held internally so typing does not require a round trip
|
|
18
|
+
* through the consumer, while `value` remains the externally controlled seed.
|
|
19
|
+
*/
|
|
20
|
+
private draft;
|
|
21
|
+
/** Fired on submit with the trimmed query. */
|
|
22
|
+
rpSearch: EventEmitter<string>;
|
|
23
|
+
/** Fired when the user clears a non-empty field. */
|
|
24
|
+
rpClear: EventEmitter<void>;
|
|
25
|
+
onValueChange(next: string): void;
|
|
26
|
+
componentWillLoad(): void;
|
|
27
|
+
private onSubmit;
|
|
28
|
+
private onInput;
|
|
29
|
+
private onClear;
|
|
30
|
+
render(): any;
|
|
31
|
+
}
|
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/* tslint:disable */
|
|
3
|
+
/**
|
|
4
|
+
* This is an autogenerated file created by the Stencil compiler.
|
|
5
|
+
* It contains typing information for all components that exist in this project.
|
|
6
|
+
*/
|
|
7
|
+
import { HTMLStencilElement, JSXBase } from "./stencil-public-runtime";
|
|
8
|
+
import { PlannedMeal } from "./components/rp-day-slot/rp-day-slot";
|
|
9
|
+
export { PlannedMeal } from "./components/rp-day-slot/rp-day-slot";
|
|
10
|
+
export namespace Components {
|
|
11
|
+
/**
|
|
12
|
+
* One day column of a weekly meal plan.
|
|
13
|
+
* Moving a meal is a select rather than drag-and-drop: it works with a keyboard and on
|
|
14
|
+
* touch without a fallback path, and the plan is small enough that dragging adds nothing.
|
|
15
|
+
*/
|
|
16
|
+
interface RpDaySlot {
|
|
17
|
+
/**
|
|
18
|
+
* Machine-readable day key, echoed in every event.
|
|
19
|
+
*/
|
|
20
|
+
"day": string;
|
|
21
|
+
/**
|
|
22
|
+
* Human-readable day name shown as the column heading.
|
|
23
|
+
* @default ''
|
|
24
|
+
*/
|
|
25
|
+
"dayLabel": string;
|
|
26
|
+
/**
|
|
27
|
+
* All day keys, used to populate each meal's move target list.
|
|
28
|
+
* @default []
|
|
29
|
+
*/
|
|
30
|
+
"days": string[];
|
|
31
|
+
/**
|
|
32
|
+
* Meals planned for this day. Must be assigned as a DOM property.
|
|
33
|
+
* @default []
|
|
34
|
+
*/
|
|
35
|
+
"meals": PlannedMeal[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A single-select row of filter chips.
|
|
39
|
+
* Selecting the active chip clears the filter, so the event detail is nullable —
|
|
40
|
+
* consumers translate null into "remove this search param".
|
|
41
|
+
*/
|
|
42
|
+
interface RpFilterChips {
|
|
43
|
+
/**
|
|
44
|
+
* Accessible label for the group.
|
|
45
|
+
* @default 'Filter'
|
|
46
|
+
*/
|
|
47
|
+
"label": string;
|
|
48
|
+
/**
|
|
49
|
+
* Available filter values. An array has no attribute representation, so this must be assigned as a DOM property. Frameworks that set properties on custom elements do this automatically.
|
|
50
|
+
* @default []
|
|
51
|
+
*/
|
|
52
|
+
"options": string[];
|
|
53
|
+
/**
|
|
54
|
+
* Currently active value, or null when no filter is applied.
|
|
55
|
+
* @default null
|
|
56
|
+
*/
|
|
57
|
+
"selected": string | null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A measure-and-name ingredient table.
|
|
61
|
+
*/
|
|
62
|
+
interface RpIngredientList {
|
|
63
|
+
/**
|
|
64
|
+
* Ingredients to display. Must be assigned as a DOM property, not an attribute.
|
|
65
|
+
* @default []
|
|
66
|
+
*/
|
|
67
|
+
"items": Array<{ name: string; measure: string }>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A modal dialog with a focus trap.
|
|
71
|
+
* Escape and focus containment are handled here rather than left to consumers, because
|
|
72
|
+
* getting them wrong is the usual reason a hand-rolled modal is inaccessible.
|
|
73
|
+
*/
|
|
74
|
+
interface RpModal {
|
|
75
|
+
/**
|
|
76
|
+
* Moves focus to the first focusable control inside the dialog. Exposed as a method because "move focus now" is a one-shot action with no state to represent; a prop would have to be toggled and reset to fire it twice.
|
|
77
|
+
*/
|
|
78
|
+
"focusFirstField": () => Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Dialog heading, also used as its accessible name.
|
|
81
|
+
* @default ''
|
|
82
|
+
*/
|
|
83
|
+
"heading": string;
|
|
84
|
+
/**
|
|
85
|
+
* Whether the dialog is visible.
|
|
86
|
+
* @default false
|
|
87
|
+
*/
|
|
88
|
+
"open": boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A recipe summary tile.
|
|
92
|
+
* Takes only primitives, so it can be driven from plain HTML attributes with no
|
|
93
|
+
* framework present. It has no idea where a recipe comes from or what a route is —
|
|
94
|
+
* consumers inject navigation through the `actions` slot.
|
|
95
|
+
*/
|
|
96
|
+
interface RpRecipeCard {
|
|
97
|
+
/**
|
|
98
|
+
* Category label shown under the heading.
|
|
99
|
+
*/
|
|
100
|
+
"category"?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Whether this recipe is currently a favorite. Reflected for CSS hooks.
|
|
103
|
+
* @default false
|
|
104
|
+
*/
|
|
105
|
+
"favorite": boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Absolute URL of the recipe image.
|
|
108
|
+
*/
|
|
109
|
+
"image"?: string;
|
|
110
|
+
/**
|
|
111
|
+
* Identifier echoed back in the toggle event so consumers know which card fired.
|
|
112
|
+
*/
|
|
113
|
+
"recipeId": string;
|
|
114
|
+
/**
|
|
115
|
+
* Recipe name, rendered as the card heading. Named `recipeTitle` rather than `title` because every HTMLElement already defines `title` on its prototype; shadowing it produces inconsistent behaviour across browsers.
|
|
116
|
+
*/
|
|
117
|
+
"recipeTitle": string;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* A search input that emits on submit rather than on every keystroke.
|
|
121
|
+
* Per-keystroke events would race the consumer's own navigation: each one triggers a
|
|
122
|
+
* server round trip, and a slow response can land after the user has typed more,
|
|
123
|
+
* overwriting the field. Submitting explicitly keeps the interaction deterministic.
|
|
124
|
+
*/
|
|
125
|
+
interface RpSearchBar {
|
|
126
|
+
/**
|
|
127
|
+
* Accessible label for the input.
|
|
128
|
+
* @default 'Search recipes'
|
|
129
|
+
*/
|
|
130
|
+
"label": string;
|
|
131
|
+
/**
|
|
132
|
+
* Placeholder shown when the field is empty.
|
|
133
|
+
* @default 'Search recipes'
|
|
134
|
+
*/
|
|
135
|
+
"placeholder": string;
|
|
136
|
+
/**
|
|
137
|
+
* Initial query text. Changing it externally resets the field.
|
|
138
|
+
* @default ''
|
|
139
|
+
*/
|
|
140
|
+
"value": string;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export interface RpDaySlotCustomEvent<T> extends CustomEvent<T> {
|
|
144
|
+
detail: T;
|
|
145
|
+
target: HTMLRpDaySlotElement;
|
|
146
|
+
}
|
|
147
|
+
export interface RpFilterChipsCustomEvent<T> extends CustomEvent<T> {
|
|
148
|
+
detail: T;
|
|
149
|
+
target: HTMLRpFilterChipsElement;
|
|
150
|
+
}
|
|
151
|
+
export interface RpModalCustomEvent<T> extends CustomEvent<T> {
|
|
152
|
+
detail: T;
|
|
153
|
+
target: HTMLRpModalElement;
|
|
154
|
+
}
|
|
155
|
+
export interface RpRecipeCardCustomEvent<T> extends CustomEvent<T> {
|
|
156
|
+
detail: T;
|
|
157
|
+
target: HTMLRpRecipeCardElement;
|
|
158
|
+
}
|
|
159
|
+
export interface RpSearchBarCustomEvent<T> extends CustomEvent<T> {
|
|
160
|
+
detail: T;
|
|
161
|
+
target: HTMLRpSearchBarElement;
|
|
162
|
+
}
|
|
163
|
+
declare global {
|
|
164
|
+
interface HTMLRpDaySlotElementEventMap {
|
|
165
|
+
"rpAddMeal": string;
|
|
166
|
+
"rpRemoveMeal": { id: string; day: string };
|
|
167
|
+
"rpMoveMeal": { id: string; from: string; to: string };
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* One day column of a weekly meal plan.
|
|
171
|
+
* Moving a meal is a select rather than drag-and-drop: it works with a keyboard and on
|
|
172
|
+
* touch without a fallback path, and the plan is small enough that dragging adds nothing.
|
|
173
|
+
*/
|
|
174
|
+
interface HTMLRpDaySlotElement extends Components.RpDaySlot, HTMLStencilElement {
|
|
175
|
+
addEventListener<K extends keyof HTMLRpDaySlotElementEventMap>(type: K, listener: (this: HTMLRpDaySlotElement, ev: RpDaySlotCustomEvent<HTMLRpDaySlotElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
|
176
|
+
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
177
|
+
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
178
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
179
|
+
removeEventListener<K extends keyof HTMLRpDaySlotElementEventMap>(type: K, listener: (this: HTMLRpDaySlotElement, ev: RpDaySlotCustomEvent<HTMLRpDaySlotElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
|
180
|
+
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
181
|
+
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
182
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
183
|
+
}
|
|
184
|
+
var HTMLRpDaySlotElement: {
|
|
185
|
+
prototype: HTMLRpDaySlotElement;
|
|
186
|
+
new (): HTMLRpDaySlotElement;
|
|
187
|
+
};
|
|
188
|
+
interface HTMLRpFilterChipsElementEventMap {
|
|
189
|
+
"rpFilterChange": string | null;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* A single-select row of filter chips.
|
|
193
|
+
* Selecting the active chip clears the filter, so the event detail is nullable —
|
|
194
|
+
* consumers translate null into "remove this search param".
|
|
195
|
+
*/
|
|
196
|
+
interface HTMLRpFilterChipsElement extends Components.RpFilterChips, HTMLStencilElement {
|
|
197
|
+
addEventListener<K extends keyof HTMLRpFilterChipsElementEventMap>(type: K, listener: (this: HTMLRpFilterChipsElement, ev: RpFilterChipsCustomEvent<HTMLRpFilterChipsElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
|
198
|
+
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
199
|
+
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
200
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
201
|
+
removeEventListener<K extends keyof HTMLRpFilterChipsElementEventMap>(type: K, listener: (this: HTMLRpFilterChipsElement, ev: RpFilterChipsCustomEvent<HTMLRpFilterChipsElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
|
202
|
+
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
203
|
+
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
204
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
205
|
+
}
|
|
206
|
+
var HTMLRpFilterChipsElement: {
|
|
207
|
+
prototype: HTMLRpFilterChipsElement;
|
|
208
|
+
new (): HTMLRpFilterChipsElement;
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* A measure-and-name ingredient table.
|
|
212
|
+
*/
|
|
213
|
+
interface HTMLRpIngredientListElement extends Components.RpIngredientList, HTMLStencilElement {
|
|
214
|
+
}
|
|
215
|
+
var HTMLRpIngredientListElement: {
|
|
216
|
+
prototype: HTMLRpIngredientListElement;
|
|
217
|
+
new (): HTMLRpIngredientListElement;
|
|
218
|
+
};
|
|
219
|
+
interface HTMLRpModalElementEventMap {
|
|
220
|
+
"rpClose": void;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* A modal dialog with a focus trap.
|
|
224
|
+
* Escape and focus containment are handled here rather than left to consumers, because
|
|
225
|
+
* getting them wrong is the usual reason a hand-rolled modal is inaccessible.
|
|
226
|
+
*/
|
|
227
|
+
interface HTMLRpModalElement extends Components.RpModal, HTMLStencilElement {
|
|
228
|
+
addEventListener<K extends keyof HTMLRpModalElementEventMap>(type: K, listener: (this: HTMLRpModalElement, ev: RpModalCustomEvent<HTMLRpModalElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
|
229
|
+
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
230
|
+
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
231
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
232
|
+
removeEventListener<K extends keyof HTMLRpModalElementEventMap>(type: K, listener: (this: HTMLRpModalElement, ev: RpModalCustomEvent<HTMLRpModalElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
|
233
|
+
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
234
|
+
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
235
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
236
|
+
}
|
|
237
|
+
var HTMLRpModalElement: {
|
|
238
|
+
prototype: HTMLRpModalElement;
|
|
239
|
+
new (): HTMLRpModalElement;
|
|
240
|
+
};
|
|
241
|
+
interface HTMLRpRecipeCardElementEventMap {
|
|
242
|
+
"rpFavoriteToggle": { recipeId: string; favorite: boolean };
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* A recipe summary tile.
|
|
246
|
+
* Takes only primitives, so it can be driven from plain HTML attributes with no
|
|
247
|
+
* framework present. It has no idea where a recipe comes from or what a route is —
|
|
248
|
+
* consumers inject navigation through the `actions` slot.
|
|
249
|
+
*/
|
|
250
|
+
interface HTMLRpRecipeCardElement extends Components.RpRecipeCard, HTMLStencilElement {
|
|
251
|
+
addEventListener<K extends keyof HTMLRpRecipeCardElementEventMap>(type: K, listener: (this: HTMLRpRecipeCardElement, ev: RpRecipeCardCustomEvent<HTMLRpRecipeCardElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
|
252
|
+
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
253
|
+
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
254
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
255
|
+
removeEventListener<K extends keyof HTMLRpRecipeCardElementEventMap>(type: K, listener: (this: HTMLRpRecipeCardElement, ev: RpRecipeCardCustomEvent<HTMLRpRecipeCardElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
|
256
|
+
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
257
|
+
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
258
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
259
|
+
}
|
|
260
|
+
var HTMLRpRecipeCardElement: {
|
|
261
|
+
prototype: HTMLRpRecipeCardElement;
|
|
262
|
+
new (): HTMLRpRecipeCardElement;
|
|
263
|
+
};
|
|
264
|
+
interface HTMLRpSearchBarElementEventMap {
|
|
265
|
+
"rpSearch": string;
|
|
266
|
+
"rpClear": void;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* A search input that emits on submit rather than on every keystroke.
|
|
270
|
+
* Per-keystroke events would race the consumer's own navigation: each one triggers a
|
|
271
|
+
* server round trip, and a slow response can land after the user has typed more,
|
|
272
|
+
* overwriting the field. Submitting explicitly keeps the interaction deterministic.
|
|
273
|
+
*/
|
|
274
|
+
interface HTMLRpSearchBarElement extends Components.RpSearchBar, HTMLStencilElement {
|
|
275
|
+
addEventListener<K extends keyof HTMLRpSearchBarElementEventMap>(type: K, listener: (this: HTMLRpSearchBarElement, ev: RpSearchBarCustomEvent<HTMLRpSearchBarElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
|
276
|
+
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
277
|
+
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
278
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
279
|
+
removeEventListener<K extends keyof HTMLRpSearchBarElementEventMap>(type: K, listener: (this: HTMLRpSearchBarElement, ev: RpSearchBarCustomEvent<HTMLRpSearchBarElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
|
280
|
+
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
281
|
+
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
282
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
283
|
+
}
|
|
284
|
+
var HTMLRpSearchBarElement: {
|
|
285
|
+
prototype: HTMLRpSearchBarElement;
|
|
286
|
+
new (): HTMLRpSearchBarElement;
|
|
287
|
+
};
|
|
288
|
+
interface HTMLElementTagNameMap {
|
|
289
|
+
"rp-day-slot": HTMLRpDaySlotElement;
|
|
290
|
+
"rp-filter-chips": HTMLRpFilterChipsElement;
|
|
291
|
+
"rp-ingredient-list": HTMLRpIngredientListElement;
|
|
292
|
+
"rp-modal": HTMLRpModalElement;
|
|
293
|
+
"rp-recipe-card": HTMLRpRecipeCardElement;
|
|
294
|
+
"rp-search-bar": HTMLRpSearchBarElement;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
declare namespace LocalJSX {
|
|
298
|
+
type OneOf<K extends string, PropT, AttrT = PropT> = { [P in K]: PropT } & { [P in `attr:${K}`]?: never } | { [P in `attr:${K}`]: AttrT } & { [P in K]?: never };
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* One day column of a weekly meal plan.
|
|
302
|
+
* Moving a meal is a select rather than drag-and-drop: it works with a keyboard and on
|
|
303
|
+
* touch without a fallback path, and the plan is small enough that dragging adds nothing.
|
|
304
|
+
*/
|
|
305
|
+
interface RpDaySlot {
|
|
306
|
+
/**
|
|
307
|
+
* Machine-readable day key, echoed in every event.
|
|
308
|
+
*/
|
|
309
|
+
"day": string;
|
|
310
|
+
/**
|
|
311
|
+
* Human-readable day name shown as the column heading.
|
|
312
|
+
* @default ''
|
|
313
|
+
*/
|
|
314
|
+
"dayLabel"?: string;
|
|
315
|
+
/**
|
|
316
|
+
* All day keys, used to populate each meal's move target list.
|
|
317
|
+
* @default []
|
|
318
|
+
*/
|
|
319
|
+
"days"?: string[];
|
|
320
|
+
/**
|
|
321
|
+
* Meals planned for this day. Must be assigned as a DOM property.
|
|
322
|
+
* @default []
|
|
323
|
+
*/
|
|
324
|
+
"meals"?: PlannedMeal[];
|
|
325
|
+
/**
|
|
326
|
+
* Fired when the user asks to add a meal to this day.
|
|
327
|
+
*/
|
|
328
|
+
"onRpAddMeal"?: (event: RpDaySlotCustomEvent<string>) => void;
|
|
329
|
+
/**
|
|
330
|
+
* Fired when a meal is reassigned to a different day.
|
|
331
|
+
*/
|
|
332
|
+
"onRpMoveMeal"?: (event: RpDaySlotCustomEvent<{ id: string; from: string; to: string }>) => void;
|
|
333
|
+
/**
|
|
334
|
+
* Fired when a meal is removed from this day.
|
|
335
|
+
*/
|
|
336
|
+
"onRpRemoveMeal"?: (event: RpDaySlotCustomEvent<{ id: string; day: string }>) => void;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* A single-select row of filter chips.
|
|
340
|
+
* Selecting the active chip clears the filter, so the event detail is nullable —
|
|
341
|
+
* consumers translate null into "remove this search param".
|
|
342
|
+
*/
|
|
343
|
+
interface RpFilterChips {
|
|
344
|
+
/**
|
|
345
|
+
* Accessible label for the group.
|
|
346
|
+
* @default 'Filter'
|
|
347
|
+
*/
|
|
348
|
+
"label"?: string;
|
|
349
|
+
/**
|
|
350
|
+
* Fired with the new selection, or null when the filter is cleared.
|
|
351
|
+
*/
|
|
352
|
+
"onRpFilterChange"?: (event: RpFilterChipsCustomEvent<string | null>) => void;
|
|
353
|
+
/**
|
|
354
|
+
* Available filter values. An array has no attribute representation, so this must be assigned as a DOM property. Frameworks that set properties on custom elements do this automatically.
|
|
355
|
+
* @default []
|
|
356
|
+
*/
|
|
357
|
+
"options"?: string[];
|
|
358
|
+
/**
|
|
359
|
+
* Currently active value, or null when no filter is applied.
|
|
360
|
+
* @default null
|
|
361
|
+
*/
|
|
362
|
+
"selected"?: string | null;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* A measure-and-name ingredient table.
|
|
366
|
+
*/
|
|
367
|
+
interface RpIngredientList {
|
|
368
|
+
/**
|
|
369
|
+
* Ingredients to display. Must be assigned as a DOM property, not an attribute.
|
|
370
|
+
* @default []
|
|
371
|
+
*/
|
|
372
|
+
"items"?: Array<{ name: string; measure: string }>;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* A modal dialog with a focus trap.
|
|
376
|
+
* Escape and focus containment are handled here rather than left to consumers, because
|
|
377
|
+
* getting them wrong is the usual reason a hand-rolled modal is inaccessible.
|
|
378
|
+
*/
|
|
379
|
+
interface RpModal {
|
|
380
|
+
/**
|
|
381
|
+
* Dialog heading, also used as its accessible name.
|
|
382
|
+
* @default ''
|
|
383
|
+
*/
|
|
384
|
+
"heading"?: string;
|
|
385
|
+
/**
|
|
386
|
+
* Fired when the user dismisses the dialog via Escape, the backdrop, or the close button.
|
|
387
|
+
*/
|
|
388
|
+
"onRpClose"?: (event: RpModalCustomEvent<void>) => void;
|
|
389
|
+
/**
|
|
390
|
+
* Whether the dialog is visible.
|
|
391
|
+
* @default false
|
|
392
|
+
*/
|
|
393
|
+
"open"?: boolean;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* A recipe summary tile.
|
|
397
|
+
* Takes only primitives, so it can be driven from plain HTML attributes with no
|
|
398
|
+
* framework present. It has no idea where a recipe comes from or what a route is —
|
|
399
|
+
* consumers inject navigation through the `actions` slot.
|
|
400
|
+
*/
|
|
401
|
+
interface RpRecipeCard {
|
|
402
|
+
/**
|
|
403
|
+
* Category label shown under the heading.
|
|
404
|
+
*/
|
|
405
|
+
"category"?: string;
|
|
406
|
+
/**
|
|
407
|
+
* Whether this recipe is currently a favorite. Reflected for CSS hooks.
|
|
408
|
+
* @default false
|
|
409
|
+
*/
|
|
410
|
+
"favorite"?: boolean;
|
|
411
|
+
/**
|
|
412
|
+
* Absolute URL of the recipe image.
|
|
413
|
+
*/
|
|
414
|
+
"image"?: string;
|
|
415
|
+
/**
|
|
416
|
+
* Fired when the favorite control is activated.
|
|
417
|
+
*/
|
|
418
|
+
"onRpFavoriteToggle"?: (event: RpRecipeCardCustomEvent<{ recipeId: string; favorite: boolean }>) => void;
|
|
419
|
+
/**
|
|
420
|
+
* Identifier echoed back in the toggle event so consumers know which card fired.
|
|
421
|
+
*/
|
|
422
|
+
"recipeId": string;
|
|
423
|
+
/**
|
|
424
|
+
* Recipe name, rendered as the card heading. Named `recipeTitle` rather than `title` because every HTMLElement already defines `title` on its prototype; shadowing it produces inconsistent behaviour across browsers.
|
|
425
|
+
*/
|
|
426
|
+
"recipeTitle": string;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* A search input that emits on submit rather than on every keystroke.
|
|
430
|
+
* Per-keystroke events would race the consumer's own navigation: each one triggers a
|
|
431
|
+
* server round trip, and a slow response can land after the user has typed more,
|
|
432
|
+
* overwriting the field. Submitting explicitly keeps the interaction deterministic.
|
|
433
|
+
*/
|
|
434
|
+
interface RpSearchBar {
|
|
435
|
+
/**
|
|
436
|
+
* Accessible label for the input.
|
|
437
|
+
* @default 'Search recipes'
|
|
438
|
+
*/
|
|
439
|
+
"label"?: string;
|
|
440
|
+
/**
|
|
441
|
+
* Fired when the user clears a non-empty field.
|
|
442
|
+
*/
|
|
443
|
+
"onRpClear"?: (event: RpSearchBarCustomEvent<void>) => void;
|
|
444
|
+
/**
|
|
445
|
+
* Fired on submit with the trimmed query.
|
|
446
|
+
*/
|
|
447
|
+
"onRpSearch"?: (event: RpSearchBarCustomEvent<string>) => void;
|
|
448
|
+
/**
|
|
449
|
+
* Placeholder shown when the field is empty.
|
|
450
|
+
* @default 'Search recipes'
|
|
451
|
+
*/
|
|
452
|
+
"placeholder"?: string;
|
|
453
|
+
/**
|
|
454
|
+
* Initial query text. Changing it externally resets the field.
|
|
455
|
+
* @default ''
|
|
456
|
+
*/
|
|
457
|
+
"value"?: string;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
interface RpDaySlotAttributes {
|
|
461
|
+
"day": string;
|
|
462
|
+
"dayLabel": string;
|
|
463
|
+
}
|
|
464
|
+
interface RpFilterChipsAttributes {
|
|
465
|
+
"selected": string | null;
|
|
466
|
+
"label": string;
|
|
467
|
+
}
|
|
468
|
+
interface RpModalAttributes {
|
|
469
|
+
"open": boolean;
|
|
470
|
+
"heading": string;
|
|
471
|
+
}
|
|
472
|
+
interface RpRecipeCardAttributes {
|
|
473
|
+
"recipeId": string;
|
|
474
|
+
"recipeTitle": string;
|
|
475
|
+
"image": string;
|
|
476
|
+
"category": string;
|
|
477
|
+
"favorite": boolean;
|
|
478
|
+
}
|
|
479
|
+
interface RpSearchBarAttributes {
|
|
480
|
+
"value": string;
|
|
481
|
+
"placeholder": string;
|
|
482
|
+
"label": string;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
interface IntrinsicElements {
|
|
486
|
+
"rp-day-slot": Omit<RpDaySlot, keyof RpDaySlotAttributes> & { [K in keyof RpDaySlot & keyof RpDaySlotAttributes]?: RpDaySlot[K] } & { [K in keyof RpDaySlot & keyof RpDaySlotAttributes as `attr:${K}`]?: RpDaySlotAttributes[K] } & { [K in keyof RpDaySlot & keyof RpDaySlotAttributes as `prop:${K}`]?: RpDaySlot[K] } & OneOf<"day", RpDaySlot["day"], RpDaySlotAttributes["day"]>;
|
|
487
|
+
"rp-filter-chips": Omit<RpFilterChips, keyof RpFilterChipsAttributes> & { [K in keyof RpFilterChips & keyof RpFilterChipsAttributes]?: RpFilterChips[K] } & { [K in keyof RpFilterChips & keyof RpFilterChipsAttributes as `attr:${K}`]?: RpFilterChipsAttributes[K] } & { [K in keyof RpFilterChips & keyof RpFilterChipsAttributes as `prop:${K}`]?: RpFilterChips[K] };
|
|
488
|
+
"rp-ingredient-list": RpIngredientList;
|
|
489
|
+
"rp-modal": Omit<RpModal, keyof RpModalAttributes> & { [K in keyof RpModal & keyof RpModalAttributes]?: RpModal[K] } & { [K in keyof RpModal & keyof RpModalAttributes as `attr:${K}`]?: RpModalAttributes[K] } & { [K in keyof RpModal & keyof RpModalAttributes as `prop:${K}`]?: RpModal[K] };
|
|
490
|
+
"rp-recipe-card": Omit<RpRecipeCard, keyof RpRecipeCardAttributes> & { [K in keyof RpRecipeCard & keyof RpRecipeCardAttributes]?: RpRecipeCard[K] } & { [K in keyof RpRecipeCard & keyof RpRecipeCardAttributes as `attr:${K}`]?: RpRecipeCardAttributes[K] } & { [K in keyof RpRecipeCard & keyof RpRecipeCardAttributes as `prop:${K}`]?: RpRecipeCard[K] } & OneOf<"recipeId", RpRecipeCard["recipeId"], RpRecipeCardAttributes["recipeId"]> & OneOf<"recipeTitle", RpRecipeCard["recipeTitle"], RpRecipeCardAttributes["recipeTitle"]>;
|
|
491
|
+
"rp-search-bar": Omit<RpSearchBar, keyof RpSearchBarAttributes> & { [K in keyof RpSearchBar & keyof RpSearchBarAttributes]?: RpSearchBar[K] } & { [K in keyof RpSearchBar & keyof RpSearchBarAttributes as `attr:${K}`]?: RpSearchBarAttributes[K] } & { [K in keyof RpSearchBar & keyof RpSearchBarAttributes as `prop:${K}`]?: RpSearchBar[K] };
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
export { LocalJSX as JSX };
|
|
495
|
+
declare module "@stencil/core" {
|
|
496
|
+
export namespace JSX {
|
|
497
|
+
interface IntrinsicElements {
|
|
498
|
+
/**
|
|
499
|
+
* One day column of a weekly meal plan.
|
|
500
|
+
* Moving a meal is a select rather than drag-and-drop: it works with a keyboard and on
|
|
501
|
+
* touch without a fallback path, and the plan is small enough that dragging adds nothing.
|
|
502
|
+
*/
|
|
503
|
+
"rp-day-slot": LocalJSX.IntrinsicElements["rp-day-slot"] & JSXBase.HTMLAttributes<HTMLRpDaySlotElement>;
|
|
504
|
+
/**
|
|
505
|
+
* A single-select row of filter chips.
|
|
506
|
+
* Selecting the active chip clears the filter, so the event detail is nullable —
|
|
507
|
+
* consumers translate null into "remove this search param".
|
|
508
|
+
*/
|
|
509
|
+
"rp-filter-chips": LocalJSX.IntrinsicElements["rp-filter-chips"] & JSXBase.HTMLAttributes<HTMLRpFilterChipsElement>;
|
|
510
|
+
/**
|
|
511
|
+
* A measure-and-name ingredient table.
|
|
512
|
+
*/
|
|
513
|
+
"rp-ingredient-list": LocalJSX.IntrinsicElements["rp-ingredient-list"] & JSXBase.HTMLAttributes<HTMLRpIngredientListElement>;
|
|
514
|
+
/**
|
|
515
|
+
* A modal dialog with a focus trap.
|
|
516
|
+
* Escape and focus containment are handled here rather than left to consumers, because
|
|
517
|
+
* getting them wrong is the usual reason a hand-rolled modal is inaccessible.
|
|
518
|
+
*/
|
|
519
|
+
"rp-modal": LocalJSX.IntrinsicElements["rp-modal"] & JSXBase.HTMLAttributes<HTMLRpModalElement>;
|
|
520
|
+
/**
|
|
521
|
+
* A recipe summary tile.
|
|
522
|
+
* Takes only primitives, so it can be driven from plain HTML attributes with no
|
|
523
|
+
* framework present. It has no idea where a recipe comes from or what a route is —
|
|
524
|
+
* consumers inject navigation through the `actions` slot.
|
|
525
|
+
*/
|
|
526
|
+
"rp-recipe-card": LocalJSX.IntrinsicElements["rp-recipe-card"] & JSXBase.HTMLAttributes<HTMLRpRecipeCardElement>;
|
|
527
|
+
/**
|
|
528
|
+
* A search input that emits on submit rather than on every keystroke.
|
|
529
|
+
* Per-keystroke events would race the consumer's own navigation: each one triggers a
|
|
530
|
+
* server round trip, and a slow response can land after the user has typed more,
|
|
531
|
+
* overwriting the field. Submitting explicitly keeps the interaction deterministic.
|
|
532
|
+
*/
|
|
533
|
+
"rp-search-bar": LocalJSX.IntrinsicElements["rp-search-bar"] & JSXBase.HTMLAttributes<HTMLRpSearchBarElement>;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public entry point for the type surface of this library.
|
|
3
|
+
*
|
|
4
|
+
* Components are not exported here. Consumers register the custom elements through
|
|
5
|
+
* `recipe-planner-ui/loader` (see README) and reference the tags directly in markup.
|
|
6
|
+
*/
|
|
7
|
+
export type * from './components.d.ts';
|