|
1 | 1 | <script lang="ts"> |
2 | 2 | import { copy } from '$lib/helpers/copy'; |
3 | 3 | import { Button } from '$lib/elements/forms'; |
4 | | - import { ActionMenu, Alert, Icon, Layout, Popover, Typography } from '@appwrite.io/pink-svelte'; |
| 4 | + import { |
| 5 | + ActionMenu, |
| 6 | + Alert, |
| 7 | + Icon, |
| 8 | + Layout, |
| 9 | + Popover, |
| 10 | + Typography, |
| 11 | + Button as PinkButton |
| 12 | + } from '@appwrite.io/pink-svelte'; |
5 | 13 | import { IconChevronDown, IconChevronUp, IconLovable } from '@appwrite.io/pink-icons-svelte'; |
6 | 14 | import { addNotification } from '$lib/stores/notifications'; |
7 | 15 | import { buildPlatformConfig, generatePromptFromConfig, type LLMPromptConfig } from './store'; |
|
99 | 107 | </script> |
100 | 108 |
|
101 | 109 | {#if showAlert} |
102 | | - <div class="custom-inline-alert"> |
103 | | - <Alert.Inline |
104 | | - status="info" |
105 | | - title="Set up your starter kit with AI" |
106 | | - dismissible |
107 | | - on:dismiss={() => (showAlert = false)}> |
108 | | - <svelte:fragment slot="icon"> |
109 | | - <IconAINotification /> |
110 | | - </svelte:fragment> |
111 | | - <Layout.Stack direction="column" class="alert-content" gap="l"> |
112 | | - <Layout.Stack direction="column" alignItems="center" gap="s"> |
113 | | - <Typography.Text> |
114 | | - Copy the prompt or open it directly in an AI tool like Cursor or Lovable to |
115 | | - get step-by-step instructions, starter code, and SDK commands for your |
116 | | - project. |
117 | | - </Typography.Text> |
118 | | - </Layout.Stack> |
| 110 | + <Alert.Inline |
| 111 | + status="info" |
| 112 | + title="Set up your starter kit with AI" |
| 113 | + dismissible |
| 114 | + --bgcolor-neutral-default="var(--bgcolor-neutral-primary)" |
| 115 | + --fgcolor-info="var(--fgcolor-neutral-primary)" |
| 116 | + on:dismiss={() => (showAlert = false)}> |
| 117 | + <svelte:fragment slot="icon"> |
| 118 | + <IconAINotification /> |
| 119 | + </svelte:fragment> |
| 120 | + <Layout.Stack direction="column" class="alert-content" gap="l"> |
| 121 | + <Layout.Stack direction="column" alignItems="center" gap="s"> |
| 122 | + <Typography.Text> |
| 123 | + Copy the prompt or open it directly in an AI tool like Cursor or Lovable to get |
| 124 | + step-by-step instructions, starter code, and SDK commands for your project. |
| 125 | + </Typography.Text> |
| 126 | + </Layout.Stack> |
119 | 127 |
|
120 | | - <Layout.Stack direction="row" alignItems="stretch" gap="none"> |
| 128 | + <Popover let:toggle let:showing padding="none" placement="bottom-start"> |
| 129 | + <svelte:fragment slot="tooltip" let:toggle> |
| 130 | + <ActionMenu.Root> |
| 131 | + {#each validOpeners as openerId} |
| 132 | + {@const o = openersConfig[openerId]} |
| 133 | + {#if o} |
| 134 | + <ActionMenu.Item.Button |
| 135 | + on:click={(e) => { |
| 136 | + window.open( |
| 137 | + o.href(prompt), |
| 138 | + '_blank', |
| 139 | + 'noopener,noreferrer' |
| 140 | + ); |
| 141 | + toggle(e); |
| 142 | + }}> |
| 143 | + <Layout.Stack direction="row" gap="s" alignItems="center"> |
| 144 | + <Avatar size="s" alt={o.alt}> |
| 145 | + {#if o.icon} |
| 146 | + <Icon icon={o.icon} size="l" /> |
| 147 | + {:else if o.imgSrc} |
| 148 | + <img src={o.imgSrc} alt={o.alt} /> |
| 149 | + {/if} |
| 150 | + </Avatar> |
| 151 | + <Layout.Stack gap="none"> |
| 152 | + <Typography.Text |
| 153 | + color="--fgcolor-neutral-secondary" |
| 154 | + variant="m-500">{o.label}</Typography.Text> |
| 155 | + <Typography.Text color="--fgcolor-neutral-tertiary"> |
| 156 | + {o.description} |
| 157 | + </Typography.Text> |
| 158 | + </Layout.Stack> |
| 159 | + </Layout.Stack> |
| 160 | + </ActionMenu.Item.Button> |
| 161 | + {/if} |
| 162 | + {/each} |
| 163 | + </ActionMenu.Root> |
| 164 | + </svelte:fragment> |
| 165 | + <PinkButton.Split> |
121 | 166 | <Button |
122 | 167 | secondary |
123 | 168 | size="s" |
124 | 169 | class={validOpeners.length ? 'btn-no-right-radius' : ''} |
125 | 170 | on:click={copyPrompt} |
126 | 171 | disabled={!prompt || prompt.length === 0}>Copy setup prompt</Button> |
127 | 172 | {#if validOpeners.length} |
128 | | - <Popover let:toggle let:showing padding="none" placement="bottom-start"> |
129 | | - <Button |
130 | | - secondary |
131 | | - size="s" |
132 | | - class="btn-no-left-radius" |
133 | | - icon |
134 | | - on:click={toggle} |
135 | | - ariaLabel="Open action menu" |
136 | | - disabled={!prompt || prompt.length === 0}> |
137 | | - <Icon icon={showing ? IconChevronUp : IconChevronDown} /> |
138 | | - </Button> |
139 | | - |
140 | | - <svelte:fragment slot="tooltip" let:toggle> |
141 | | - <ActionMenu.Root> |
142 | | - {#each validOpeners as openerId} |
143 | | - {@const o = openersConfig[openerId]} |
144 | | - {#if o} |
145 | | - <ActionMenu.Item.Button |
146 | | - on:click={(e) => { |
147 | | - window.open( |
148 | | - o.href(prompt), |
149 | | - '_blank', |
150 | | - 'noopener,noreferrer' |
151 | | - ); |
152 | | - toggle(e); |
153 | | - }}> |
154 | | - <Layout.Stack |
155 | | - direction="row" |
156 | | - gap="s" |
157 | | - alignItems="center"> |
158 | | - <Avatar size="s" alt={o.alt}> |
159 | | - {#if o.icon} |
160 | | - <Icon icon={o.icon} size="l" /> |
161 | | - {:else if o.imgSrc} |
162 | | - <img src={o.imgSrc} alt={o.alt} /> |
163 | | - {/if} |
164 | | - </Avatar> |
165 | | - <Layout.Stack gap="none"> |
166 | | - <Typography.Text |
167 | | - color="--fgcolor-neutral-secondary" |
168 | | - variant="m-500" |
169 | | - >{o.label}</Typography.Text> |
170 | | - <Typography.Text |
171 | | - color="--fgcolor-neutral-tertiary"> |
172 | | - {o.description} |
173 | | - </Typography.Text> |
174 | | - </Layout.Stack> |
175 | | - </Layout.Stack> |
176 | | - </ActionMenu.Item.Button> |
177 | | - {/if} |
178 | | - {/each} |
179 | | - </ActionMenu.Root> |
180 | | - </svelte:fragment> |
181 | | - </Popover> |
| 173 | + <Button |
| 174 | + secondary |
| 175 | + size="s" |
| 176 | + class="btn-no-left-radius" |
| 177 | + icon |
| 178 | + on:click={toggle} |
| 179 | + ariaLabel="Open action menu" |
| 180 | + disabled={!prompt || prompt.length === 0}> |
| 181 | + <Icon icon={showing ? IconChevronUp : IconChevronDown} /> |
| 182 | + </Button> |
182 | 183 | {/if} |
183 | | - </Layout.Stack> |
184 | | - </Layout.Stack> |
185 | | - </Alert.Inline> |
186 | | - </div> |
| 184 | + </PinkButton.Split> |
| 185 | + </Popover> |
| 186 | + </Layout.Stack> |
| 187 | + </Alert.Inline> |
187 | 188 | {/if} |
188 | | - |
189 | | -<style lang="scss"> |
190 | | - :global(.btn-no-right-radius), |
191 | | - :global(button.btn-no-right-radius), |
192 | | - :global(.button.btn-no-right-radius) { |
193 | | - border-top-right-radius: 0 !important; |
194 | | - border-bottom-right-radius: 0 !important; |
195 | | - border-right: none !important; |
196 | | - } |
197 | | -
|
198 | | - :global(.btn-no-left-radius), |
199 | | - :global(button.btn-no-left-radius), |
200 | | - :global(.button.btn-no-left-radius) { |
201 | | - border-top-left-radius: 0 !important; |
202 | | - border-bottom-left-radius: 0 !important; |
203 | | - } |
204 | | -
|
205 | | - :global(.menu-avatar img) { |
206 | | - width: 20px; |
207 | | - height: 20px; |
208 | | - object-fit: contain; |
209 | | - display: block; |
210 | | - } |
211 | | -
|
212 | | - .custom-inline-alert { |
213 | | - & :global(article) { |
214 | | - border-radius: var(--border-radius-medium); |
215 | | - padding: var(--space-6, 12px); |
216 | | - padding-right: var(--space-4, 12px); |
217 | | - background: var(--bgcolor-neutral-primary); |
218 | | - border: var(--border-width-s) solid var(--border-neutral); |
219 | | - } |
220 | | - & :global(article > div) { |
221 | | - gap: var(--space-6); |
222 | | - } |
223 | | - & :global(.ai-icon-holder.notification) { |
224 | | - height: 36px !important; |
225 | | - } |
226 | | -
|
227 | | - & :global(h5) { |
228 | | - font-weight: 500 !important; |
229 | | - color: var(--fgcolor-neutral-primary) !important; |
230 | | - } |
231 | | -
|
232 | | - & :global(p) { |
233 | | - color: var(--fgcolor-neutral-secondary) !important; |
234 | | - } |
235 | | -
|
236 | | - & :global(.alert-content) { |
237 | | - margin-top: 2px !important; |
238 | | - } |
239 | | -
|
240 | | - & :global([role='tooltip'] > div) { |
241 | | - gap: var(--space-2, 4px) !important; |
242 | | - } |
243 | | - } |
244 | | -</style> |
0 commit comments