tangled
alpha
login
or
join now
flo-bit.dev
/
blento
21
fork
atom
your personal website on atproto - mirror
blento.app
21
fork
atom
overview
issues
pulls
pipelines
button card
unbedenklich
1 month ago
3f182c5f
78d08bfc
+131
-26
6 changed files
expand all
collapse all
unified
split
.claude
settings.local.json
src
lib
cards
ButtonCard
ButtonCard.svelte
ButtonCardSettings.svelte
EditingButtonCard.svelte
index.ts
index.ts
+27
-26
.claude/settings.local.json
···
1
1
{
2
2
-
"permissions": {
3
3
-
"allow": [
4
4
-
"Bash(pnpm check:*)",
5
5
-
"mcp__ide__getDiagnostics",
6
6
-
"mcp__plugin_svelte_svelte__svelte-autofixer",
7
7
-
"mcp__plugin_svelte_svelte__list-sections",
8
8
-
"Bash(pkill:*)",
9
9
-
"Bash(timeout 8 pnpm dev:*)",
10
10
-
"Bash(git checkout:*)",
11
11
-
"Bash(npx svelte-kit:*)",
12
12
-
"Bash(ls:*)",
13
13
-
"Bash(pnpm format:*)",
14
14
-
"Bash(pnpm add:*)",
15
15
-
"WebSearch",
16
16
-
"WebFetch(domain:github.com)",
17
17
-
"WebFetch(domain:flipclockjs.com)",
18
18
-
"WebFetch(domain:codepen.io)",
19
19
-
"WebFetch(domain:flo-bit.dev)",
20
20
-
"Bash(pnpm install)",
21
21
-
"Bash(pnpm install:*)",
22
22
-
"Bash(pnpm config:*)",
23
23
-
"Bash(lsof:*)",
24
24
-
"Bash(pnpm dev)",
25
25
-
"Bash(pnpm exec svelte-kit:*)"
26
26
-
]
27
27
-
}
2
2
+
"permissions": {
3
3
+
"allow": [
4
4
+
"Bash(pnpm check:*)",
5
5
+
"mcp__ide__getDiagnostics",
6
6
+
"mcp__plugin_svelte_svelte__svelte-autofixer",
7
7
+
"mcp__plugin_svelte_svelte__list-sections",
8
8
+
"Bash(pkill:*)",
9
9
+
"Bash(timeout 8 pnpm dev:*)",
10
10
+
"Bash(git checkout:*)",
11
11
+
"Bash(npx svelte-kit:*)",
12
12
+
"Bash(ls:*)",
13
13
+
"Bash(pnpm format:*)",
14
14
+
"Bash(pnpm add:*)",
15
15
+
"WebSearch",
16
16
+
"WebFetch(domain:github.com)",
17
17
+
"WebFetch(domain:flipclockjs.com)",
18
18
+
"WebFetch(domain:codepen.io)",
19
19
+
"WebFetch(domain:flo-bit.dev)",
20
20
+
"Bash(pnpm install)",
21
21
+
"Bash(pnpm install:*)",
22
22
+
"Bash(pnpm config:*)",
23
23
+
"Bash(lsof:*)",
24
24
+
"Bash(pnpm dev)",
25
25
+
"Bash(pnpm exec svelte-kit:*)",
26
26
+
"Bash(pnpm build:*)"
27
27
+
]
28
28
+
}
28
29
}
+18
src/lib/cards/ButtonCard/ButtonCard.svelte
···
1
1
+
<script lang="ts">
2
2
+
import type { ContentComponentProps } from '../types';
3
3
+
4
4
+
let { item }: ContentComponentProps = $props();
5
5
+
</script>
6
6
+
7
7
+
<a
8
8
+
href={item.cardData.href || '#'}
9
9
+
target="_blank"
10
10
+
rel="noopener noreferrer"
11
11
+
class="flex h-full w-full items-center justify-center p-4"
12
12
+
>
13
13
+
<span
14
14
+
class="bg-accent-500 hover:bg-accent-600 text-base-50 inline-flex items-center justify-center rounded-xl px-6 py-3 text-center font-semibold shadow-md transition-colors"
15
15
+
>
16
16
+
{item.cardData.text || 'Click me'}
17
17
+
</span>
18
18
+
</a>
+34
src/lib/cards/ButtonCard/ButtonCardSettings.svelte
···
1
1
+
<script lang="ts">
2
2
+
import type { Item } from '$lib/types';
3
3
+
import type { SettingsComponentProps } from '../types';
4
4
+
import { Input, Label } from '@foxui/core';
5
5
+
6
6
+
let { item = $bindable<Item>(), onclose }: SettingsComponentProps = $props();
7
7
+
8
8
+
function confirmUrl() {
9
9
+
let href = item.cardData.href?.trim() || '';
10
10
+
if (href && !/^https?:\/\//i.test(href)) {
11
11
+
href = 'https://' + href;
12
12
+
}
13
13
+
item.cardData.href = href;
14
14
+
onclose();
15
15
+
}
16
16
+
</script>
17
17
+
18
18
+
<div class="flex flex-col gap-3">
19
19
+
<div class="flex flex-col gap-1">
20
20
+
<Label for="button-href" class="text-sm">Link URL</Label>
21
21
+
<Input
22
22
+
id="button-href"
23
23
+
bind:value={item.cardData.href}
24
24
+
placeholder="youtube.com"
25
25
+
class="text-sm"
26
26
+
onkeydown={(event) => {
27
27
+
if (event.code === 'Enter') {
28
28
+
event.preventDefault();
29
29
+
confirmUrl();
30
30
+
}
31
31
+
}}
32
32
+
/>
33
33
+
</div>
34
34
+
</div>
+19
src/lib/cards/ButtonCard/EditingButtonCard.svelte
···
1
1
+
<script lang="ts">
2
2
+
import type { ContentComponentProps } from '../types';
3
3
+
import PlainTextEditor from '$lib/components/PlainTextEditor.svelte';
4
4
+
5
5
+
let { item = $bindable() }: ContentComponentProps = $props();
6
6
+
</script>
7
7
+
8
8
+
<div class="flex h-full w-full flex-col items-center justify-center gap-2 p-4">
9
9
+
<div
10
10
+
class="bg-accent-500 text-base-50 inline-flex items-center justify-center rounded-xl px-6 py-3 shadow-md"
11
11
+
>
12
12
+
<PlainTextEditor
13
13
+
key="text"
14
14
+
bind:contentDict={item.cardData}
15
15
+
placeholder="Button text"
16
16
+
class="text-center font-semibold"
17
17
+
/>
18
18
+
</div>
19
19
+
</div>
+31
src/lib/cards/ButtonCard/index.ts
···
1
1
+
import type { CardDefinition } from '../types';
2
2
+
import ButtonCard from './ButtonCard.svelte';
3
3
+
import EditingButtonCard from './EditingButtonCard.svelte';
4
4
+
import ButtonCardSettings from './ButtonCardSettings.svelte';
5
5
+
6
6
+
export const ButtonCardDefinition: CardDefinition = {
7
7
+
type: 'button',
8
8
+
contentComponent: ButtonCard,
9
9
+
editingContentComponent: EditingButtonCard,
10
10
+
settingsComponent: ButtonCardSettings,
11
11
+
sidebarButtonText: 'Button',
12
12
+
13
13
+
createNew: (card) => {
14
14
+
card.cardData = {
15
15
+
text: 'Click me'
16
16
+
};
17
17
+
card.w = 2;
18
18
+
card.h = 1;
19
19
+
card.mobileW = 4;
20
20
+
card.mobileH = 2;
21
21
+
},
22
22
+
23
23
+
defaultColor: 'transparent',
24
24
+
allowSetColor: true,
25
25
+
canHaveLabel: false,
26
26
+
27
27
+
minW: 2,
28
28
+
minH: 1,
29
29
+
maxW: 8,
30
30
+
maxH: 4
31
31
+
};
+2
src/lib/cards/index.ts
···
31
31
import { DrawCardDefinition } from './DrawCard';
32
32
import { TimerCardDefinition } from './TimerCard';
33
33
import { SpotifyCardDefinition } from './SpotifyCard';
34
34
+
import { ButtonCardDefinition } from './ButtonCard';
34
35
// import { Model3DCardDefinition } from './Model3DCard';
35
36
36
37
export const AllCardDefinitions = [
38
38
+
ButtonCardDefinition,
37
39
ImageCardDefinition,
38
40
VideoCardDefinition,
39
41
TextCardDefinition,