Skip to content

Commit 94df3a3

Browse files
committed
wip: init form
1 parent cfd413c commit 94df3a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+3560
-1288
lines changed

.ref/@kaption2/core/plugin-forms/themes/cardDeck/CardEnd.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts" setup>
2-
import { vue } from '@factor/api'
2+
import { vue } from '@fiction/core'
33
import type { Card } from '../../card'
44
import type { Form } from '../../form'
55
import EditableText from './EditableText.vue'

.ref/@kaption2/core/plugin-forms/themes/cardDeck/ThemeIndex.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<script lang="ts" setup>
2-
import { getColorScheme, vue, windowSize } from '@factor/api'
2+
import { getColorScheme, vue, windowSize } from '@fiction/core'
33
import chroma from 'chroma-js'
4-
import ElRichImage from '@factor/ui/ElRichImage.vue'
5-
import ElOverlay from '@factor/ui/ElOverlay.vue'
4+
import ElRichImage from '@fiction/ui/media/ElImage.vue'
5+
import ElOverlay from '@fiction/ui/ElOverlay.vue'
66
import type { Form } from '../../form'
77
import FormProgressBar from './FormProgressBar.vue'
88
import type { EntryProps } from './theme'

.ref/@kaption2/core/plugin-forms/themes/cardDeck/theme.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
// // @unocss-include
2-
import type { ColorScheme, UserFont } from '@factor/api'
3-
import { vue } from '@factor/api'
4-
import type { GradientSetting, MediaDisplayObject } from '@factor/ui/utils'
1+
2+
import type { ColorTheme, GradientSetting, UserFont } from '@fiction/core'
3+
import { vue } from '@fiction/core'
54
import type { Card } from '../../card'
65
import { FormTheme } from '../../card'
76

87
import type { Form } from '../../form'
9-
import { InputOption } from '../../../utils/inputOption'
8+
import { InputOption } from '@fiction/ui'
109
import { standardCardOptions } from '../../cardOptions'
1110
import { CardType, standardCardTypes } from '../../cardTypes'
1211
import CardStandard from './CardStandard.vue'
@@ -30,7 +29,7 @@ export type CardLayoutMode = typeof cardLayoutMode[number]
3029

3130
export interface EntryProps {
3231
actionColor?: string
33-
elementScheme?: ColorScheme
32+
elementScheme?: ColorTheme
3433
bgColor: string
3534
bgImage?: MediaDisplayObject[]
3635
bgGradient?: GradientSetting

@fiction/admin/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"animejs": "^3.2.2",
1212
"mapbox-gl": "^3.5.2",
1313
"tailwindcss": "^3.4.7",
14-
"vue": "^3.4.34"
14+
"vue": "^3.4.35"
1515
},
1616
"devDependencies": {
1717
"@types/animejs": "^3.1.12",

@fiction/cards/CardElement.vue

-24
This file was deleted.

@fiction/cards/contact/ElCard.vue

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<script setup lang="ts">
2+
import { vue } from '@fiction/core'
3+
import type { Card } from '@fiction/site'
4+
import { useElementVisible } from '@fiction/ui/anim'
5+
import CardText from '../CardText.vue'
6+
import CardSocials from '../el/CardSocials.vue'
7+
import type { UserConfig } from '.'
8+
9+
const props = defineProps({
10+
card: {
11+
type: Object as vue.PropType<Card<UserConfig>>,
12+
required: true,
13+
},
14+
})
15+
16+
const uc = vue.computed(() => {
17+
return props.card.userConfig.value || {}
18+
})
19+
20+
const items = vue.computed(() => uc.value.items)
21+
22+
const isVisible = vue.ref(false)
23+
vue.onMounted(async () => {
24+
await useElementVisible({ selector: `.minimal-profile`, onVisible: () => isVisible.value = true })
25+
})
26+
27+
vue.onMounted(() => {
28+
// Load the Typeform embed script
29+
const script = document.createElement('script')
30+
script.src = '//embed.typeform.com/next/embed.js'
31+
script.async = true
32+
document.body.appendChild(script)
33+
})
34+
</script>
35+
36+
<template>
37+
<div class="minimal-profile" :class="card.classes.value.contentWidth">
38+
<div>
39+
<div class="md:flex gap-16 " :class="uc.layout === 'left' ? 'md:flex-row-reverse' : ''">
40+
<div class="w-full md:w-[50%] px-2">
41+
<div class="relative border border-theme-200 dark:border-theme-700 rounded-xl h-full bg-theme-50 dark:bg-theme-700/50">
42+
<div data-tf-live="01J462G1SZ6TQ1HE9210GYRXPD" />
43+
</div>
44+
</div>
45+
<div class="md:w-[50%] mt-6 md:mt-0 flex items-center">
46+
<div class="p-6 flex flex-col justify-center gap-10 2xl:gap-12 " :class="isVisible ? 'translate-y-0' : 'translate-y-[100px]'">
47+
<div class="details space-y-4">
48+
<CardText
49+
tag="h3"
50+
:card
51+
class="text-primary-300 dark:text-primary-400 mb-4 text-sm font-sans font-medium"
52+
path="superTitle"
53+
animate="rise"
54+
/>
55+
<CardText
56+
tag="h1"
57+
:card
58+
class="heading text-4xl font-semibold md:text-5xl x-font-title lg:leading-[1.1] text-balance"
59+
path="title"
60+
animate="rise"
61+
/>
62+
<CardText
63+
tag="div"
64+
:card
65+
class="sub-heading text-lg dark:text-theme-400"
66+
path="subTitle"
67+
:is-markdown="true"
68+
animate="rise"
69+
/>
70+
</div>
71+
72+
<div v-for="(item, i) in items" :key="i" class="list">
73+
<CardText
74+
tag="h3"
75+
:card
76+
class="sub-heading dark:text-theme-200 x-font-title text-lg md:text-xl font-semibold mb-4"
77+
:path="`items.${i}.title`"
78+
placeholder="List Title"
79+
/>
80+
<div class="flex gap-[10%] gap-y-4 flex-wrap text-base ">
81+
<div v-for="(subItem, ii) in item.items" :key="ii" class="flex gap-4 items-center">
82+
<div class="text-4xl" :class="subItem.icon" />
83+
<CardText
84+
:card
85+
tag="a"
86+
class="text-lg"
87+
:path="`items.${i}.items.${ii}.title`"
88+
:href="subItem.href"
89+
/>
90+
</div>
91+
</div>
92+
</div>
93+
94+
<CardSocials :card :socials="uc.socials || []" class="flex gap-2 text-2xl justify-center md:justify-start" />
95+
</div>
96+
</div>
97+
</div>
98+
</div>
99+
</div>
100+
</template>

@fiction/cards/contact/index.ts

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { vue } from '@fiction/core'
2+
import { CardTemplate } from '@fiction/site/card'
3+
import { z } from 'zod'
4+
import { standardOption } from '../inputSets'
5+
6+
const templateId = 'contact'
7+
8+
export const UserConfigSchema = z.object({
9+
layout: z.enum(['left', 'right']).optional().describe('Layout of the card, image on left or right'),
10+
title: z.string().optional().describe('Primary headline for profile 3 to 8 words'),
11+
subTitle: z.string().optional().describe('Formatted markdown of profile with paragraphs, 30 to 60 words, 2 paragraphs'),
12+
superTitle: z.string().optional().describe('Shorter badge above headline, 2 to 5 words'),
13+
items: z.array(z.object({
14+
title: z.string().optional().describe('Title for list of details'),
15+
items: z.array(z.object({
16+
title: z.string().optional(),
17+
content: z.string().optional(),
18+
icon: z.string().optional(),
19+
href: z.string().optional(),
20+
})).optional().describe('List of details with contact details, location, etc.'),
21+
})),
22+
socials: z.array(z.object({
23+
name: z.string().optional().describe('@handle on (platform)'),
24+
href: z.string().optional().describe('Full link for href'),
25+
icon: z.string().optional().describe('icon reference associated with the social media platform (x, youtube, facebook, etc)'),
26+
})).optional().describe('List of social media links'),
27+
})
28+
29+
export type UserConfig = z.infer<typeof UserConfigSchema>
30+
31+
const options = [
32+
standardOption.ai(),
33+
]
34+
35+
const defaultContent: UserConfig = {
36+
superTitle: 'Contact',
37+
title: 'Get In Touch',
38+
subTitle: `Send me a message and I'll respond within 24 hours.`,
39+
items: [
40+
{
41+
title: 'Chat with Me',
42+
items: [
43+
{ title: 'Send me an email', content: '[email protected]', href: 'mailto:[email protected]', icon: 'i-tabler-mail' },
44+
],
45+
},
46+
{
47+
title: 'Call Me',
48+
items: [
49+
{ title: '+1(888) 888-8888', content: '', href: '#', icon: 'i-tabler-phone' },
50+
],
51+
},
52+
],
53+
54+
socials: [
55+
{ name: '@handle on facebook', href: '#', icon: 'facebook' },
56+
{ name: '@handle on x', href: '#', icon: 'x' },
57+
{ name: '@handle on linkedin', href: '#', icon: 'linkedin' },
58+
],
59+
}
60+
61+
export const templates = [
62+
new CardTemplate({
63+
templateId,
64+
category: ['form', 'marketing'],
65+
description: 'A minimal profile card with a splash image, headline, subheading, and contact details.',
66+
icon: 'i-tabler-user',
67+
colorTheme: 'blue',
68+
el: vue.defineAsyncComponent(async () => import('./ElCard.vue')),
69+
getUserConfig: () => defaultContent,
70+
isPublic: true,
71+
options,
72+
schema: UserConfigSchema,
73+
demoPage: async () => {
74+
return { cards: [
75+
{ templateId, userConfig: { ...defaultContent } },
76+
{ templateId, userConfig: { ...defaultContent, layout: 'left' as const } },
77+
] }
78+
},
79+
}),
80+
] as const

@fiction/cards/index.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import { z } from 'zod'
66
import type { CardConfigPortable } from '@fiction/site'
77
import * as four04 from './404'
88
import * as quote from './quote'
9-
import { templates as templatesLogos } from './logos'
9+
import * as logos from './logos'
1010
import * as hero from './hero'
1111
import * as mediaPop from './mediaPop'
1212
import * as area from './area'
1313
import * as tour from './tour'
1414
import * as profile from './profile'
15-
import { templates as templatesMediaGrid } from './media-grid'
15+
import * as mediaGrid from './media-grid'
1616
import * as metrics from './metrics'
1717
import * as features from './features'
1818
import * as people from './people'
@@ -35,7 +35,8 @@ import * as overSlide from './overSlide/index.js'
3535
import * as statement from './statement/index.js'
3636
import * as testimonials from './testimonials/index.js'
3737
import * as effectShape from './effect-shape/index.js'
38-
import * as mason from './gallery/index.js'
38+
import * as gallery from './gallery/index.js'
39+
import * as contact from './contact/index.js'
3940

4041
import { createDemoPage } from './utils/demo'
4142
/**
@@ -69,9 +70,9 @@ export const standardCardTemplates = [
6970
...ticker.templates,
7071
...people.templates,
7172
...pricing.templates,
72-
...templatesLogos,
73+
...logos.templates,
74+
...mediaGrid.templates,
7375
...tour.templates,
74-
...templatesMediaGrid,
7576
...features.templates,
7677
...metrics.templates,
7778
...faq.templates,
@@ -82,7 +83,8 @@ export const standardCardTemplates = [
8283
...statement.templates,
8384
...testimonials.templates,
8485
...effectShape.templates,
85-
...mason.templates,
86+
...gallery.templates,
87+
...contact.templates,
8688
] as const
8789

8890
export async function getCardTemplates() {

@fiction/cards/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"animejs": "^3.2.2",
1212
"mapbox-gl": "^3.5.2",
1313
"tailwindcss": "^3.4.7",
14-
"vue": "^3.4.34"
14+
"vue": "^3.4.35"
1515
},
1616
"devDependencies": {
1717
"@types/animejs": "^3.1.12",

@fiction/cards/testimonials/LayoutMega.vue

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
<script lang="ts" setup>
22
import { vue } from '@fiction/core'
33
import type { Card } from '@fiction/site'
4-
import EffectCarousel from '@fiction/ui/effect/EffectCarousel.vue'
54
import ElImage from '@fiction/ui/media/ElImage.vue'
65
import CardText from '../CardText.vue'
7-
import NavDots from '../el/NavDots.vue'
86
9-
import type { Testimonial, UserConfig } from './index.js'
7+
import type { UserConfig } from './index.js'
108
119
const props = defineProps({
1210
card: { type: Object as vue.PropType<Card<UserConfig>>, required: true },

0 commit comments

Comments
 (0)