@ssejal8/recipe-ui-kit 0.1.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/.claude/settings.local.json +10 -0
- package/.npmr +1 -0
- package/README.md +354 -0
- package/apps/recipe-web/package.json +31 -0
- package/apps/recipe-web/src/app.css +418 -0
- package/apps/recipe-web/src/app.d.ts +32 -0
- package/apps/recipe-web/src/app.html +25 -0
- package/apps/recipe-web/src/lib/api/mealdb.ts +240 -0
- package/apps/recipe-web/src/lib/components/AppHeader.svelte +290 -0
- package/apps/recipe-web/src/lib/components/ConfirmDialog.svelte +46 -0
- package/apps/recipe-web/src/lib/components/Modal.svelte +33 -0
- package/apps/recipe-web/src/lib/components/RecipeCard.svelte +100 -0
- package/apps/recipe-web/src/lib/components/RecipeForm.svelte +560 -0
- package/apps/recipe-web/src/lib/components/RecipeGrid.svelte +77 -0
- package/apps/recipe-web/src/lib/components/RecipePickerDialog.svelte +185 -0
- package/apps/recipe-web/src/lib/components/Toaster.svelte +111 -0
- package/apps/recipe-web/src/lib/domain/recipe.ts +130 -0
- package/apps/recipe-web/src/lib/domain/validation.ts +189 -0
- package/apps/recipe-web/src/lib/stencil/WebComponent.svelte +145 -0
- package/apps/recipe-web/src/lib/stencil/register.ts +28 -0
- package/apps/recipe-web/src/lib/stores/favorites.svelte.ts +81 -0
- package/apps/recipe-web/src/lib/stores/myRecipes.svelte.ts +98 -0
- package/apps/recipe-web/src/lib/stores/persisted.svelte.ts +73 -0
- package/apps/recipe-web/src/lib/stores/planner.svelte.ts +275 -0
- package/apps/recipe-web/src/lib/stores/theme.svelte.ts +67 -0
- package/apps/recipe-web/src/lib/stores/toast.svelte.ts +66 -0
- package/apps/recipe-web/src/routes/+error.svelte +36 -0
- package/apps/recipe-web/src/routes/+layout.svelte +62 -0
- package/apps/recipe-web/src/routes/+page.svelte +352 -0
- package/apps/recipe-web/src/routes/+page.ts +107 -0
- package/apps/recipe-web/src/routes/favorites/+page.svelte +170 -0
- package/apps/recipe-web/src/routes/my-recipes/+layout.ts +55 -0
- package/apps/recipe-web/src/routes/my-recipes/+page.svelte +180 -0
- package/apps/recipe-web/src/routes/my-recipes/[id]/edit/+page.svelte +104 -0
- package/apps/recipe-web/src/routes/my-recipes/new/+page.svelte +67 -0
- package/apps/recipe-web/src/routes/planner/+page.svelte +422 -0
- package/apps/recipe-web/src/routes/recipes/[id]/+page.svelte +538 -0
- package/apps/recipe-web/src/routes/recipes/[id]/+page.ts +24 -0
- package/apps/recipe-web/static/favicon.svg +8 -0
- package/apps/recipe-web/static/robots.txt +2 -0
- package/apps/recipe-web/svelte.config.js +35 -0
- package/apps/recipe-web/tsconfig.json +14 -0
- package/apps/recipe-web/vite.config.ts +23 -0
- package/package.json +29 -0
- package/packages/recipe-kit-stencil/LICENSE +21 -0
- package/packages/recipe-kit-stencil/README.md +185 -0
- package/packages/recipe-kit-stencil/package-lock.json +4772 -0
- package/packages/recipe-kit-stencil/package.json +91 -0
- package/packages/recipe-kit-stencil/src/components/rk-badge/readme.md +38 -0
- package/packages/recipe-kit-stencil/src/components/rk-badge/rk-badge.css +102 -0
- package/packages/recipe-kit-stencil/src/components/rk-badge/rk-badge.tsx +31 -0
- package/packages/recipe-kit-stencil/src/components/rk-chip/readme.md +52 -0
- package/packages/recipe-kit-stencil/src/components/rk-chip/rk-chip.css +155 -0
- package/packages/recipe-kit-stencil/src/components/rk-chip/rk-chip.tsx +105 -0
- package/packages/recipe-kit-stencil/src/components/rk-empty-state/readme.md +44 -0
- package/packages/recipe-kit-stencil/src/components/rk-empty-state/rk-empty-state.css +64 -0
- package/packages/recipe-kit-stencil/src/components/rk-empty-state/rk-empty-state.tsx +50 -0
- package/packages/recipe-kit-stencil/src/components/rk-meal-slot/readme.md +58 -0
- package/packages/recipe-kit-stencil/src/components/rk-meal-slot/rk-meal-slot.css +225 -0
- package/packages/recipe-kit-stencil/src/components/rk-meal-slot/rk-meal-slot.tsx +182 -0
- package/packages/recipe-kit-stencil/src/components/rk-modal/readme.md +57 -0
- package/packages/recipe-kit-stencil/src/components/rk-modal/rk-modal.css +163 -0
- package/packages/recipe-kit-stencil/src/components/rk-modal/rk-modal.tsx +176 -0
- package/packages/recipe-kit-stencil/src/components/rk-rating/readme.md +42 -0
- package/packages/recipe-kit-stencil/src/components/rk-rating/rk-rating.css +71 -0
- package/packages/recipe-kit-stencil/src/components/rk-rating/rk-rating.tsx +114 -0
- package/packages/recipe-kit-stencil/src/components/rk-recipe-card/readme.md +66 -0
- package/packages/recipe-kit-stencil/src/components/rk-recipe-card/rk-recipe-card.css +280 -0
- package/packages/recipe-kit-stencil/src/components/rk-recipe-card/rk-recipe-card.tsx +179 -0
- package/packages/recipe-kit-stencil/src/components/rk-recipe-card/test/rk-recipe-card.spec.tsx +70 -0
- package/packages/recipe-kit-stencil/src/components/rk-search-bar/readme.md +67 -0
- package/packages/recipe-kit-stencil/src/components/rk-search-bar/rk-search-bar.css +141 -0
- package/packages/recipe-kit-stencil/src/components/rk-search-bar/rk-search-bar.tsx +152 -0
- package/packages/recipe-kit-stencil/src/components/rk-search-bar/test/rk-search-bar.spec.tsx +93 -0
- package/packages/recipe-kit-stencil/src/components/rk-segmented-control/readme.md +41 -0
- package/packages/recipe-kit-stencil/src/components/rk-segmented-control/rk-segmented-control.css +91 -0
- package/packages/recipe-kit-stencil/src/components/rk-segmented-control/rk-segmented-control.tsx +115 -0
- package/packages/recipe-kit-stencil/src/components/rk-tag-input/readme.md +47 -0
- package/packages/recipe-kit-stencil/src/components/rk-tag-input/rk-tag-input.css +146 -0
- package/packages/recipe-kit-stencil/src/components/rk-tag-input/rk-tag-input.tsx +181 -0
- package/packages/recipe-kit-stencil/src/components/rk-tag-input/test/rk-tag-input.spec.tsx +76 -0
- package/packages/recipe-kit-stencil/src/components.d.ts +1192 -0
- package/packages/recipe-kit-stencil/src/global/rk-global.css +104 -0
- package/packages/recipe-kit-stencil/src/index.html +259 -0
- package/packages/recipe-kit-stencil/src/index.ts +6 -0
- package/packages/recipe-kit-stencil/stencil.config.ts +41 -0
- package/packages/recipe-kit-stencil/tsconfig.json +24 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* recipe-kit-stencil — design tokens.
|
|
3
|
+
*
|
|
4
|
+
* Every token is a CSS custom property, so it inherits through the shadow
|
|
5
|
+
* boundary of each component. Consumers can therefore re-theme the whole
|
|
6
|
+
* library by overriding these on :root (or on any ancestor element) without
|
|
7
|
+
* touching component internals.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
:root,
|
|
11
|
+
:host {
|
|
12
|
+
/* Brand */
|
|
13
|
+
--rk-primary: #d94f1b;
|
|
14
|
+
--rk-primary-strong: #b23c11;
|
|
15
|
+
--rk-primary-soft: #fdeee6;
|
|
16
|
+
--rk-accent: #0f766e;
|
|
17
|
+
--rk-accent-soft: #e2f3f1;
|
|
18
|
+
|
|
19
|
+
/* Neutrals / surfaces */
|
|
20
|
+
--rk-bg: #fffaf6;
|
|
21
|
+
--rk-surface: #ffffff;
|
|
22
|
+
--rk-surface-2: #fdf5ef;
|
|
23
|
+
--rk-ink: #211a16;
|
|
24
|
+
--rk-ink-2: #52443c;
|
|
25
|
+
--rk-muted: #857166;
|
|
26
|
+
--rk-border: #ecdfd4;
|
|
27
|
+
--rk-border-strong: #d9c6b8;
|
|
28
|
+
|
|
29
|
+
/* Feedback */
|
|
30
|
+
--rk-danger: #c2410c;
|
|
31
|
+
--rk-danger-soft: #fdeae1;
|
|
32
|
+
--rk-success: #15803d;
|
|
33
|
+
--rk-success-soft: #e6f5eb;
|
|
34
|
+
--rk-warning: #a16207;
|
|
35
|
+
--rk-warning-soft: #fdf3d8;
|
|
36
|
+
|
|
37
|
+
/* Shape */
|
|
38
|
+
--rk-radius-sm: 8px;
|
|
39
|
+
--rk-radius: 14px;
|
|
40
|
+
--rk-radius-lg: 20px;
|
|
41
|
+
--rk-radius-pill: 999px;
|
|
42
|
+
|
|
43
|
+
/* Elevation */
|
|
44
|
+
--rk-shadow-sm: 0 1px 2px rgba(33, 26, 22, 0.06), 0 1px 3px rgba(33, 26, 22, 0.04);
|
|
45
|
+
--rk-shadow: 0 4px 12px rgba(33, 26, 22, 0.08), 0 1px 3px rgba(33, 26, 22, 0.05);
|
|
46
|
+
--rk-shadow-lg: 0 18px 42px rgba(33, 26, 22, 0.16);
|
|
47
|
+
|
|
48
|
+
/* Type */
|
|
49
|
+
--rk-font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
50
|
+
--rk-font-display: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
|
|
51
|
+
--rk-font-size: 15px;
|
|
52
|
+
|
|
53
|
+
/* Motion */
|
|
54
|
+
--rk-transition: 160ms cubic-bezier(0.2, 0, 0.2, 1);
|
|
55
|
+
|
|
56
|
+
/* Focus */
|
|
57
|
+
--rk-focus-ring: 0 0 0 3px rgba(217, 79, 27, 0.32);
|
|
58
|
+
|
|
59
|
+
/* Layers */
|
|
60
|
+
--rk-z-modal: 1000;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
:root[data-rk-theme='dark'],
|
|
64
|
+
:root[data-theme='dark'] {
|
|
65
|
+
--rk-primary: #ff7a45;
|
|
66
|
+
--rk-primary-strong: #ff9469;
|
|
67
|
+
--rk-primary-soft: #3a2118;
|
|
68
|
+
--rk-accent: #5eead4;
|
|
69
|
+
--rk-accent-soft: #10312e;
|
|
70
|
+
|
|
71
|
+
--rk-bg: #16110e;
|
|
72
|
+
--rk-surface: #201814;
|
|
73
|
+
--rk-surface-2: #2a201a;
|
|
74
|
+
--rk-ink: #f7ece5;
|
|
75
|
+
--rk-ink-2: #d9c8bd;
|
|
76
|
+
--rk-muted: #a89387;
|
|
77
|
+
--rk-border: #38291f;
|
|
78
|
+
--rk-border-strong: #4b382c;
|
|
79
|
+
|
|
80
|
+
--rk-danger: #ff8f66;
|
|
81
|
+
--rk-danger-soft: #3a1d14;
|
|
82
|
+
--rk-success: #6ee7a0;
|
|
83
|
+
--rk-success-soft: #12301f;
|
|
84
|
+
--rk-warning: #fbbf5b;
|
|
85
|
+
--rk-warning-soft: #33260d;
|
|
86
|
+
|
|
87
|
+
--rk-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
88
|
+
--rk-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
|
|
89
|
+
--rk-shadow-lg: 0 20px 48px rgba(0, 0, 0, 0.6);
|
|
90
|
+
--rk-focus-ring: 0 0 0 3px rgba(255, 122, 69, 0.4);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* Shared, opt-in visually-hidden helper for light DOM content passed via slots. */
|
|
94
|
+
.rk-sr-only {
|
|
95
|
+
position: absolute !important;
|
|
96
|
+
width: 1px;
|
|
97
|
+
height: 1px;
|
|
98
|
+
padding: 0;
|
|
99
|
+
margin: -1px;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
clip: rect(0, 0, 0, 0);
|
|
102
|
+
white-space: nowrap;
|
|
103
|
+
border: 0;
|
|
104
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" dir="ltr">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>recipe-kit-stencil — component gallery</title>
|
|
7
|
+
<script type="module" src="/build/recipe-kit.esm.js"></script>
|
|
8
|
+
<script nomodule src="/build/recipe-kit.js"></script>
|
|
9
|
+
<style>
|
|
10
|
+
body {
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 40px 24px 96px;
|
|
13
|
+
background: var(--rk-bg);
|
|
14
|
+
color: var(--rk-ink);
|
|
15
|
+
font-family: var(--rk-font);
|
|
16
|
+
font-size: 15px;
|
|
17
|
+
}
|
|
18
|
+
main {
|
|
19
|
+
max-width: 960px;
|
|
20
|
+
margin: 0 auto;
|
|
21
|
+
display: grid;
|
|
22
|
+
gap: 44px;
|
|
23
|
+
}
|
|
24
|
+
h1 {
|
|
25
|
+
font-family: var(--rk-font-display);
|
|
26
|
+
font-size: 2.1rem;
|
|
27
|
+
margin: 0 0 6px;
|
|
28
|
+
letter-spacing: -0.02em;
|
|
29
|
+
}
|
|
30
|
+
.lede {
|
|
31
|
+
color: var(--rk-muted);
|
|
32
|
+
margin: 0;
|
|
33
|
+
max-width: 60ch;
|
|
34
|
+
line-height: 1.6;
|
|
35
|
+
}
|
|
36
|
+
section h2 {
|
|
37
|
+
font-size: 0.78rem;
|
|
38
|
+
text-transform: uppercase;
|
|
39
|
+
letter-spacing: 0.09em;
|
|
40
|
+
color: var(--rk-muted);
|
|
41
|
+
margin: 0 0 14px;
|
|
42
|
+
padding-bottom: 8px;
|
|
43
|
+
border-bottom: 1px solid var(--rk-border);
|
|
44
|
+
}
|
|
45
|
+
.row {
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-wrap: wrap;
|
|
48
|
+
gap: 12px;
|
|
49
|
+
align-items: center;
|
|
50
|
+
}
|
|
51
|
+
.grid {
|
|
52
|
+
display: grid;
|
|
53
|
+
grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
|
|
54
|
+
gap: 18px;
|
|
55
|
+
}
|
|
56
|
+
.planner {
|
|
57
|
+
display: grid;
|
|
58
|
+
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
|
59
|
+
gap: 12px;
|
|
60
|
+
}
|
|
61
|
+
button.demo {
|
|
62
|
+
font: inherit;
|
|
63
|
+
font-weight: 600;
|
|
64
|
+
padding: 9px 16px;
|
|
65
|
+
border-radius: 999px;
|
|
66
|
+
border: 1px solid var(--rk-border);
|
|
67
|
+
background: var(--rk-surface);
|
|
68
|
+
color: var(--rk-ink);
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
}
|
|
71
|
+
#log {
|
|
72
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
73
|
+
font-size: 12px;
|
|
74
|
+
background: var(--rk-ink);
|
|
75
|
+
color: #d8f5c8;
|
|
76
|
+
padding: 14px 16px;
|
|
77
|
+
border-radius: 12px;
|
|
78
|
+
max-height: 180px;
|
|
79
|
+
overflow: auto;
|
|
80
|
+
white-space: pre-wrap;
|
|
81
|
+
margin: 0;
|
|
82
|
+
}
|
|
83
|
+
</style>
|
|
84
|
+
</head>
|
|
85
|
+
<body>
|
|
86
|
+
<main>
|
|
87
|
+
<header>
|
|
88
|
+
<h1>recipe-kit-stencil</h1>
|
|
89
|
+
<p class="lede">
|
|
90
|
+
A framework-agnostic web component library built with StencilJS. Every event below is logged at the bottom of the page — the same events the
|
|
91
|
+
SvelteKit application listens for.
|
|
92
|
+
</p>
|
|
93
|
+
</header>
|
|
94
|
+
|
|
95
|
+
<section>
|
|
96
|
+
<h2>rk-search-bar</h2>
|
|
97
|
+
<rk-search-bar hint="Debounced at 350 ms. Press Escape to clear.">
|
|
98
|
+
<rk-badge slot="actions" tone="accent">beta</rk-badge>
|
|
99
|
+
</rk-search-bar>
|
|
100
|
+
</section>
|
|
101
|
+
|
|
102
|
+
<section>
|
|
103
|
+
<h2>rk-chip & rk-segmented-control</h2>
|
|
104
|
+
<div class="row">
|
|
105
|
+
<rk-chip label="Seafood" value="Seafood" count="18"><span>🐟</span></rk-chip>
|
|
106
|
+
<rk-chip label="Dessert" value="Dessert" selected tone="primary"></rk-chip>
|
|
107
|
+
<rk-chip label="Vegan" value="Vegan" tone="accent" selected></rk-chip>
|
|
108
|
+
<rk-chip label="Italian" value="Italian" dismissible></rk-chip>
|
|
109
|
+
</div>
|
|
110
|
+
<br />
|
|
111
|
+
<rk-segmented-control id="segments" label="Sort recipes"></rk-segmented-control>
|
|
112
|
+
</section>
|
|
113
|
+
|
|
114
|
+
<section>
|
|
115
|
+
<h2>rk-badge & rk-rating</h2>
|
|
116
|
+
<div class="row">
|
|
117
|
+
<rk-badge>neutral</rk-badge>
|
|
118
|
+
<rk-badge tone="primary" variant="solid">primary solid</rk-badge>
|
|
119
|
+
<rk-badge tone="accent" variant="outline">accent outline</rk-badge>
|
|
120
|
+
<rk-badge tone="success" small>30 min</rk-badge>
|
|
121
|
+
<rk-rating value="4" show-value count="128"></rk-rating>
|
|
122
|
+
<rk-rating value="3.5" readonly show-value></rk-rating>
|
|
123
|
+
</div>
|
|
124
|
+
</section>
|
|
125
|
+
|
|
126
|
+
<section>
|
|
127
|
+
<h2>rk-recipe-card</h2>
|
|
128
|
+
<div class="grid">
|
|
129
|
+
<rk-recipe-card
|
|
130
|
+
recipe-id="52772"
|
|
131
|
+
name="Teriyaki Chicken Casserole"
|
|
132
|
+
image="https://www.themealdb.com/images/media/meals/wvpsxx1468256321.jpg"
|
|
133
|
+
category="Chicken"
|
|
134
|
+
area="Japanese"
|
|
135
|
+
minutes="45"
|
|
136
|
+
servings="4"
|
|
137
|
+
href="#52772"
|
|
138
|
+
>
|
|
139
|
+
<rk-badge tone="accent" small>weeknight</rk-badge>
|
|
140
|
+
<button class="demo" slot="actions">Add to plan</button>
|
|
141
|
+
</rk-recipe-card>
|
|
142
|
+
|
|
143
|
+
<rk-recipe-card
|
|
144
|
+
recipe-id="local-1"
|
|
145
|
+
name="Grandma's Sunday Ragù"
|
|
146
|
+
category="Pasta"
|
|
147
|
+
area="Italian"
|
|
148
|
+
minutes="180"
|
|
149
|
+
origin="custom"
|
|
150
|
+
favorite
|
|
151
|
+
>
|
|
152
|
+
<rk-badge tone="warning" small>slow cook</rk-badge>
|
|
153
|
+
</rk-recipe-card>
|
|
154
|
+
|
|
155
|
+
<rk-recipe-card
|
|
156
|
+
recipe-id="52959"
|
|
157
|
+
name="Baked Salmon with Fennel & Tomatoes"
|
|
158
|
+
image="https://www.themealdb.com/images/media/meals/1548772327.jpg"
|
|
159
|
+
category="Seafood"
|
|
160
|
+
area="British"
|
|
161
|
+
minutes="30"
|
|
162
|
+
compact
|
|
163
|
+
></rk-recipe-card>
|
|
164
|
+
</div>
|
|
165
|
+
</section>
|
|
166
|
+
|
|
167
|
+
<section>
|
|
168
|
+
<h2>rk-meal-slot</h2>
|
|
169
|
+
<div class="planner">
|
|
170
|
+
<rk-meal-slot day="monday" meal-type="breakfast" meal-label="Breakfast"></rk-meal-slot>
|
|
171
|
+
<rk-meal-slot
|
|
172
|
+
day="monday"
|
|
173
|
+
meal-type="dinner"
|
|
174
|
+
meal-label="Dinner"
|
|
175
|
+
recipe-id="52772"
|
|
176
|
+
recipe-name="Teriyaki Chicken Casserole"
|
|
177
|
+
recipe-image="https://www.themealdb.com/images/media/meals/wvpsxx1468256321.jpg"
|
|
178
|
+
></rk-meal-slot>
|
|
179
|
+
<rk-meal-slot day="tuesday" meal-type="lunch" meal-label="Lunch"></rk-meal-slot>
|
|
180
|
+
</div>
|
|
181
|
+
</section>
|
|
182
|
+
|
|
183
|
+
<section>
|
|
184
|
+
<h2>rk-tag-input</h2>
|
|
185
|
+
<rk-tag-input id="tags" label="Recipe tags" max-tags="6"></rk-tag-input>
|
|
186
|
+
</section>
|
|
187
|
+
|
|
188
|
+
<section>
|
|
189
|
+
<h2>rk-modal</h2>
|
|
190
|
+
<button class="demo" id="open-modal">Open dialog</button>
|
|
191
|
+
<rk-modal id="modal" heading="Delete this recipe?" subheading="This cannot be undone.">
|
|
192
|
+
<p style="margin: 0">Removing “Grandma's Sunday Ragù” also removes it from every day of your weekly plan.</p>
|
|
193
|
+
<button class="demo" slot="footer" id="cancel-modal">Cancel</button>
|
|
194
|
+
<button class="demo" slot="footer" style="background: var(--rk-danger); border-color: var(--rk-danger); color: #fff">Delete</button>
|
|
195
|
+
</rk-modal>
|
|
196
|
+
</section>
|
|
197
|
+
|
|
198
|
+
<section>
|
|
199
|
+
<h2>rk-empty-state</h2>
|
|
200
|
+
<rk-empty-state icon="🔍" heading="No recipes matched “quinoa risotto”" message="Try a broader search term, or clear the active filters.">
|
|
201
|
+
<button class="demo">Clear filters</button>
|
|
202
|
+
</rk-empty-state>
|
|
203
|
+
</section>
|
|
204
|
+
|
|
205
|
+
<section>
|
|
206
|
+
<h2>Event log</h2>
|
|
207
|
+
<pre id="log">Interact with the components above…</pre>
|
|
208
|
+
</section>
|
|
209
|
+
</main>
|
|
210
|
+
|
|
211
|
+
<script type="module">
|
|
212
|
+
const log = document.getElementById('log');
|
|
213
|
+
let lines = [];
|
|
214
|
+
const record = (event) => {
|
|
215
|
+
lines.unshift(`${event.type} → ${JSON.stringify(event.detail)}`);
|
|
216
|
+
log.textContent = lines.slice(0, 40).join('\n');
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const events = [
|
|
220
|
+
'rkSearch', 'rkClear', 'rkChipToggle', 'rkChipDismiss', 'rkSegmentChange', 'rkRatingChange',
|
|
221
|
+
'rkCardSelect', 'rkFavoriteToggle', 'rkMealAdd', 'rkMealSwap', 'rkMealRemove', 'rkMealOpen',
|
|
222
|
+
'rkMealDrop', 'rkTagsChange', 'rkModalClose',
|
|
223
|
+
];
|
|
224
|
+
events.forEach((name) => document.addEventListener(name, record));
|
|
225
|
+
|
|
226
|
+
// Array-valued properties are assigned as DOM properties, never attributes.
|
|
227
|
+
customElements.whenDefined('rk-segmented-control').then(() => {
|
|
228
|
+
const segments = document.getElementById('segments');
|
|
229
|
+
segments.options = [
|
|
230
|
+
{ label: 'Relevance', value: 'relevance' },
|
|
231
|
+
{ label: 'A–Z', value: 'az' },
|
|
232
|
+
{ label: 'Quickest', value: 'time', count: 12 },
|
|
233
|
+
{ label: 'Unavailable', value: 'x', disabled: true },
|
|
234
|
+
];
|
|
235
|
+
segments.value = 'relevance';
|
|
236
|
+
segments.addEventListener('rkSegmentChange', (event) => (segments.value = event.detail));
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
customElements.whenDefined('rk-tag-input').then(() => {
|
|
240
|
+
const tags = document.getElementById('tags');
|
|
241
|
+
tags.values = ['comfort food', 'one pot'];
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Favorite state is owned by the host app, exactly as in SvelteKit.
|
|
245
|
+
document.addEventListener('rkFavoriteToggle', (event) => {
|
|
246
|
+
event.target.favorite = event.detail.favorite;
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
document.addEventListener('rkChipToggle', (event) => {
|
|
250
|
+
event.target.selected = event.detail.selected;
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
const modal = document.getElementById('modal');
|
|
254
|
+
document.getElementById('open-modal').addEventListener('click', () => (modal.open = true));
|
|
255
|
+
document.getElementById('cancel-modal').addEventListener('click', () => (modal.open = false));
|
|
256
|
+
modal.addEventListener('rkModalClose', () => (modal.open = false));
|
|
257
|
+
</script>
|
|
258
|
+
</body>
|
|
259
|
+
</html>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Components, JSX } from './components';
|
|
2
|
+
|
|
3
|
+
// Event payload contracts, re-exported so consumers can type their handlers.
|
|
4
|
+
export type { RkRecipeCardSelectDetail, RkFavoriteToggleDetail } from './components/rk-recipe-card/rk-recipe-card';
|
|
5
|
+
export type { RkSegmentOption } from './components/rk-segmented-control/rk-segmented-control';
|
|
6
|
+
export type { RkMealSlotDetail, RkMealRecipeDetail, RkMealDropDetail } from './components/rk-meal-slot/rk-meal-slot';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Config } from '@stencil/core';
|
|
2
|
+
|
|
3
|
+
export const config: Config = {
|
|
4
|
+
namespace: 'recipe-kit',
|
|
5
|
+
globalStyle: 'src/global/rk-global.css',
|
|
6
|
+
sourceMap: true,
|
|
7
|
+
buildEs5: false,
|
|
8
|
+
extras: {
|
|
9
|
+
enableImportInjection: true,
|
|
10
|
+
},
|
|
11
|
+
outputTargets: [
|
|
12
|
+
// Lazy-loaded distribution + `loader/` entry point. This is what the
|
|
13
|
+
// SvelteKit app consumes from npm via `recipe-kit-stencil/loader`.
|
|
14
|
+
{
|
|
15
|
+
type: 'dist',
|
|
16
|
+
esmLoaderPath: '../loader',
|
|
17
|
+
isPrimaryPackageOutputTarget: true,
|
|
18
|
+
copy: [{ src: 'global/rk-global.css', dest: 'rk-global.css', warn: true }],
|
|
19
|
+
},
|
|
20
|
+
// Standalone custom elements, for consumers that want to import a single
|
|
21
|
+
// component and define it themselves (tree-shakeable).
|
|
22
|
+
{
|
|
23
|
+
type: 'dist-custom-elements',
|
|
24
|
+
customElementsExportBehavior: 'auto-define-custom-elements',
|
|
25
|
+
externalRuntime: false,
|
|
26
|
+
generateTypeDeclarations: true,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
type: 'docs-readme',
|
|
30
|
+
footer: '*Built with [StencilJS](https://stenciljs.com/)*',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: 'www',
|
|
34
|
+
serviceWorker: null,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
testing: {
|
|
38
|
+
browserHeadless: 'shell',
|
|
39
|
+
},
|
|
40
|
+
validatePrimaryPackageOutputTarget: true,
|
|
41
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowSyntheticDefaultImports": true,
|
|
4
|
+
"allowUnreachableCode": false,
|
|
5
|
+
"declaration": false,
|
|
6
|
+
"experimentalDecorators": true,
|
|
7
|
+
"lib": ["dom", "es2020"],
|
|
8
|
+
"moduleResolution": "bundler",
|
|
9
|
+
"module": "esnext",
|
|
10
|
+
"target": "es2020",
|
|
11
|
+
"noUnusedLocals": true,
|
|
12
|
+
"noUnusedParameters": true,
|
|
13
|
+
"sourceMap": true,
|
|
14
|
+
"strictNullChecks": false,
|
|
15
|
+
"strictPropertyInitialization": false,
|
|
16
|
+
"jsx": "react",
|
|
17
|
+
"jsxFactory": "h",
|
|
18
|
+
"jsxFragmentFactory": "Fragment",
|
|
19
|
+
"esModuleInterop": true,
|
|
20
|
+
"skipLibCheck": true
|
|
21
|
+
},
|
|
22
|
+
"include": ["src"],
|
|
23
|
+
"exclude": ["node_modules", "dist", "loader", "www"]
|
|
24
|
+
}
|