@stacksjs/defaults 0.70.256 → 0.70.258
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/app/Routes.ts +2 -2
- package/ide/cursor/rules/auto-imports.mdc +1 -1
- package/ide/cursor/rules/code-style.mdc +1 -1
- package/ide/cursor/rules/error-handling-validation.mdc +2 -2
- package/ide/cursor/rules/key-conventions.mdc +1 -1
- package/ide/cursor/rules/project-structure.mdc +1 -1
- package/ide/cursor/rules/syntax-formatting.mdc +1 -1
- package/ide/cursor/rules/testing.mdc +1 -1
- package/ide/vscode/package.json +1 -1
- package/package.json +1 -1
- package/resources/components/Container.stx +1 -1
- package/resources/components/Docs/Demo/ComboboxDemo.stx +1 -1
- package/resources/components/Docs/Demo/DocsPlayground.stx +2 -2
- package/resources/components/Docs/Demo/DropdownDemo.stx +3 -3
- package/resources/components/Docs/Demo/ListboxDemo.stx +2 -2
- package/resources/components/Docs/Demo/PopoverDemo.stx +1 -1
- package/resources/components/Docs/Demo/RadioGroupDemo.stx +3 -3
- package/resources/components/Docs/Demo/StepperDemo.stx +6 -6
- package/resources/components/Docs/Demo/SwitchDemo.stx +2 -2
- package/resources/components/Forum/ForumBreadcrumb.stx +2 -2
- package/resources/components/Forum/ForumCategoryItem.stx +1 -1
- package/resources/components/Forum/ForumLayout.stx +4 -4
- package/resources/components/Forum/ForumPagination.stx +3 -3
- package/resources/components/Forum/ForumReplyForm.stx +1 -1
- package/resources/components/Marketing/Feature.stx +3 -3
- package/resources/components/Marketing/Fields.stx +3 -3
- package/resources/components/Marketing/Layout.stx +1 -1
- package/resources/components/Marketing/Plan.stx +5 -5
- package/resources/components/Marketing/Pricing.stx +5 -5
- package/resources/components/Marketing/PrimaryFeatures.stx +4 -4
- package/resources/components/Marketing/PrimaryFeatures2.stx +4 -4
- package/resources/components/Marketing/SecondaryFeatures.stx +3 -3
- package/views/[...all].stx +0 -1
- package/views/dashboard/layouts/default.stx +2 -2
package/app/Routes.ts
CHANGED
|
@@ -40,8 +40,8 @@ export default {
|
|
|
40
40
|
// so `routes/api.ts` aligns with the proxy forward path.
|
|
41
41
|
'api': 'api',
|
|
42
42
|
|
|
43
|
-
// Add versioned or prefixed routes here:
|
|
44
|
-
'v1': { path: 'v1', prefix: 'v1' }
|
|
43
|
+
// Add versioned or prefixed routes here after creating the matching file:
|
|
44
|
+
// 'v1': { path: 'v1', prefix: 'v1' },
|
|
45
45
|
// 'v2': 'api/v2',
|
|
46
46
|
// 'admin': { path: 'admin', middleware: ['auth'] },
|
|
47
47
|
} satisfies RouteRegistry
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Error Handling and Validation specifics
|
|
3
|
-
globs:
|
|
3
|
+
globs:
|
|
4
4
|
---
|
|
5
5
|
## Error Handling and Validation
|
|
6
6
|
|
|
@@ -8,4 +8,4 @@ globs:
|
|
|
8
8
|
- Use early returns and guard clauses
|
|
9
9
|
- Implement proper error logging and user-friendly messages
|
|
10
10
|
- Use error boundaries for unexpected errors
|
|
11
|
-
- Use `@stacksjs/error-handling`, which is similar to neverthrow, to handle errors and responses
|
|
11
|
+
- Use `@stacksjs/error-handling`, which is similar to neverthrow, to handle errors and responses
|
package/ide/vscode/package.json
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/defaults",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.70.
|
|
5
|
+
"version": "0.70.258",
|
|
6
6
|
"description": "The complete managed Stacks application scaffold, including runtime defaults, AI guidance, editor metadata, and npm-backed project support files.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"license": "MIT",
|
|
@@ -56,7 +56,7 @@ function filterItems(items, query) {
|
|
|
56
56
|
data-item-id="{{ item.id }}"
|
|
57
57
|
data-item-name="{{ item.name }}"
|
|
58
58
|
>
|
|
59
|
-
<span class="block truncate selected selected.id
|
|
59
|
+
<span class="block truncate {{ selected && selected.id == item.id ? 'font-medium' : 'font-normal' }}">
|
|
60
60
|
{{ item.name }}
|
|
61
61
|
</span>
|
|
62
62
|
@if(selected && selected.id == item.id)
|
|
@@ -10,13 +10,13 @@ const { isPreviewMode = true } = defineProps<DocsPlaygroundProps>()
|
|
|
10
10
|
<div class="relative bg-gray-100 dark:bg-neutral-800 rounded-lg">
|
|
11
11
|
<div class="flex items-stretch justify-end px-3 py-1 md:m-1 bg-gray-100 dark:bg-neutral-800 rounded-t-[10px] md:rounded-lg">
|
|
12
12
|
<button
|
|
13
|
-
class="
|
|
13
|
+
class="pointer-events-auto mr-1 flex rounded-md px-3 py-2 text-xs font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/50 {{ isPreviewMode ? 'bg-white text-blue-500' : 'text-gray-600 dark:text-neutral-300 hover:bg-gray-300 dark:hover:bg-neutral-600' }}"
|
|
14
14
|
data-action="toggle-preview"
|
|
15
15
|
>
|
|
16
16
|
Preview
|
|
17
17
|
</button>
|
|
18
18
|
<button
|
|
19
|
-
class="flex px-3 py-2
|
|
19
|
+
class="pointer-events-auto flex rounded-md px-3 py-2 text-xs font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/50 {{ !isPreviewMode ? 'bg-white text-blue-500' : 'text-gray-600 dark:text-neutral-300 hover:bg-gray-300 dark:hover:bg-neutral-600' }}"
|
|
20
20
|
data-action="toggle-code"
|
|
21
21
|
>
|
|
22
22
|
Code
|
|
@@ -45,7 +45,7 @@ function getMenuSections(items) {
|
|
|
45
45
|
data-action="toggle-dropdown"
|
|
46
46
|
>
|
|
47
47
|
Options
|
|
48
|
-
<div class="
|
|
48
|
+
<div class="i-hugeicons-chevron-down-20-solid w-5 h-5 transition-transform duration-200 {{ isOpen ? 'rotate-180' : '' }}"></div>
|
|
49
49
|
</button>
|
|
50
50
|
|
|
51
51
|
@if(isOpen)
|
|
@@ -55,11 +55,11 @@ function getMenuSections(items) {
|
|
|
55
55
|
@foreach(section as item)
|
|
56
56
|
<button
|
|
57
57
|
type="button"
|
|
58
|
-
class="
|
|
58
|
+
class="group relative flex w-full items-center rounded-md px-2 py-2 text-sm outline-none transition-colors {{ item.variant == 'danger' ? 'text-red-600 hover:bg-red-50' : 'text-gray-700 hover:bg-gray-50' }}"
|
|
59
59
|
data-action="menu-item"
|
|
60
60
|
data-item-label="{{ item.label }}"
|
|
61
61
|
>
|
|
62
|
-
<div class="mr-2 h-5 w-5
|
|
62
|
+
<div class="{{ item.icon }} mr-2 h-5 w-5 {{ item.variant == 'danger' ? 'text-red-600' : 'text-gray-500 group-hover:text-gray-700' }}"></div>
|
|
63
63
|
{{ item.label }}
|
|
64
64
|
</button>
|
|
65
65
|
@endforeach
|
|
@@ -32,12 +32,12 @@ const { people = [, selectedPerson = people[0], isOpen = false } = defineProps<L
|
|
|
32
32
|
<div class="absolute overflow-auto mt-1 py-1 max-h-60 w-full text-base sm:text-sm bg-white outline-none ring-1 ring-black/5 rounded-md focus:outline-none shadow-lg">
|
|
33
33
|
@foreach(people as person)
|
|
34
34
|
<div
|
|
35
|
-
class="relative
|
|
35
|
+
class="list-none relative cursor-default select-none py-2 pl-10 pr-4 hover:bg-amber-100 hover:text-amber-900 {{ selectedPerson.id == person.id ? 'bg-amber-100 text-amber-900' : 'text-gray-900' }}"
|
|
36
36
|
data-action="select-person"
|
|
37
37
|
data-person-id="{{ person.id }}"
|
|
38
38
|
data-person-name="{{ person.name }}"
|
|
39
39
|
>
|
|
40
|
-
<span class="block truncate selectedPerson.id
|
|
40
|
+
<span class="block truncate {{ selectedPerson.id == person.id ? 'font-medium' : 'font-normal' }}">
|
|
41
41
|
{{ person.name }}
|
|
42
42
|
</span>
|
|
43
43
|
@if(selectedPerson.id == person.id)
|
|
@@ -34,7 +34,7 @@ const { solutions = [, isOpen = false } = defineProps<PopoverDemoProps>()
|
|
|
34
34
|
<div class="items-center mx-auto my-12 space-y-4 h-[150px] w-3/5">
|
|
35
35
|
<div class="relative">
|
|
36
36
|
<button
|
|
37
|
-
class="inline-flex
|
|
37
|
+
class="group inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-lg shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-all duration-200 {{ isOpen ? 'text-white' : 'text-white/90' }}"
|
|
38
38
|
data-action="toggle-popover"
|
|
39
39
|
>
|
|
40
40
|
<span>Example</span>
|
|
@@ -16,17 +16,17 @@ const { plans = [, selected = plans[0] } = defineProps<RadioGroupDemoProps>()
|
|
|
16
16
|
<div class="space-y-2">
|
|
17
17
|
@foreach(plans as plan)
|
|
18
18
|
<div
|
|
19
|
-
class="flex
|
|
19
|
+
class="relative flex cursor-pointer rounded-lg px-5 py-4 shadow-md focus:outline-none {{ selected.name == plan.name ? 'bg-sky-900/75 text-white ring-2 ring-white/60 ring-offset-2 ring-offset-sky-300' : 'bg-white' }}"
|
|
20
20
|
data-action="select-plan"
|
|
21
21
|
data-plan-name="{{ plan.name }}"
|
|
22
22
|
>
|
|
23
23
|
<div class="flex items-center justify-between w-full">
|
|
24
24
|
<div class="flex items-center">
|
|
25
25
|
<div class="text-sm">
|
|
26
|
-
<p class="font-medium selected.name
|
|
26
|
+
<p class="font-medium {{ selected.name == plan.name ? 'text-white' : 'text-gray-900' }}">
|
|
27
27
|
{{ plan.name }}
|
|
28
28
|
</p>
|
|
29
|
-
<span class="inline selected.name
|
|
29
|
+
<span class="inline {{ selected.name == plan.name ? 'text-sky-100' : 'text-gray-500' }}">
|
|
30
30
|
<span>{{ plan.ram }}/{{ plan.cpus }}</span>
|
|
31
31
|
<span aria-hidden="true"> · </span>
|
|
32
32
|
<span>{{ plan.disk }}</span>
|
|
@@ -30,19 +30,19 @@ function getStepContent(step) {
|
|
|
30
30
|
<!-- Stepper indicator -->
|
|
31
31
|
<div class="flex items-center justify-between mb-12">
|
|
32
32
|
@foreach(steps as step)
|
|
33
|
-
<div class="flex items-center
|
|
33
|
+
<div class="flex items-center {{ loop.last ? '' : 'flex-1' }}">
|
|
34
34
|
<div class="flex flex-col items-center">
|
|
35
|
-
<div class="flex items-center justify-center
|
|
35
|
+
<div class="flex items-center justify-center w-8 h-8 rounded-full {{ loop.index <= currentStep ? 'bg-blue-100 text-blue-600' : 'bg-gray-100 text-gray-500' }} {{ loop.index == currentStep ? 'ring-2 ring-blue-600 ring-offset-2' : '' }}">
|
|
36
36
|
@if(loop.index < currentStep)
|
|
37
37
|
<div class="h-5 w-5 i-heroicons-check"></div>
|
|
38
38
|
@else
|
|
39
39
|
{{ loop.index + 1 }}
|
|
40
40
|
@endif
|
|
41
41
|
</div>
|
|
42
|
-
<span class="mt-2
|
|
42
|
+
<span class="mt-2 text-sm {{ loop.index == currentStep ? 'text-blue-600 font-medium' : 'text-gray-500' }}">{{ step.title }}</span>
|
|
43
43
|
</div>
|
|
44
44
|
@if(!loop.last)
|
|
45
|
-
<div class="flex-1
|
|
45
|
+
<div class="flex-1 h-0.5 mx-4 {{ loop.index < currentStep ? 'bg-blue-500' : 'bg-gray-200' }}"></div>
|
|
46
46
|
@endif
|
|
47
47
|
</div>
|
|
48
48
|
@endforeach
|
|
@@ -108,14 +108,14 @@ function getStepContent(step) {
|
|
|
108
108
|
|
|
109
109
|
<div class="flex gap-4 justify-center">
|
|
110
110
|
<button
|
|
111
|
-
class="px-4 py-2 font-medium text-gray-700
|
|
111
|
+
class="rounded-md bg-gray-50 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 {{ currentStep == 0 ? 'opacity-50 cursor-not-allowed' : '' }}"
|
|
112
112
|
data-action="previous-step"
|
|
113
113
|
{{ currentStep == 0 ? 'disabled' : '' }}
|
|
114
114
|
>
|
|
115
115
|
Previous
|
|
116
116
|
</button>
|
|
117
117
|
<button
|
|
118
|
-
class="px-4 py-2 font-medium text-
|
|
118
|
+
class="rounded-md bg-blue-500 px-4 py-2 text-sm font-medium text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 {{ currentStep == steps.length - 1 ? 'opacity-50 cursor-not-allowed' : '' }}"
|
|
119
119
|
data-action="next-step"
|
|
120
120
|
{{ currentStep == steps.length - 1 ? 'disabled' : '' }}
|
|
121
121
|
>
|
|
@@ -9,13 +9,13 @@ const { enabled = false } = defineProps<SwitchDemoProps>()
|
|
|
9
9
|
<DocsPlayground>
|
|
10
10
|
<div class="flex gap-2 items-center justify-center my-3">
|
|
11
11
|
<button
|
|
12
|
-
class="
|
|
12
|
+
class="relative h-[38px] w-[74px] inline-flex shrink-0 cursor-pointer border-2 border-transparent rounded-full transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-white/75 {{ enabled ? 'bg-blue-500' : 'bg-gray-400' }}"
|
|
13
13
|
data-action="toggle-switch"
|
|
14
14
|
>
|
|
15
15
|
<span class="sr-only">Use setting</span>
|
|
16
16
|
<span
|
|
17
17
|
aria-hidden="true"
|
|
18
|
-
class="inline-block h-[34px] w-[34px] bg-white ring-0
|
|
18
|
+
class="pointer-events-none inline-block h-[34px] w-[34px] transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out {{ enabled ? 'translate-x-9' : 'translate-x-0' }}"
|
|
19
19
|
></span>
|
|
20
20
|
</button>
|
|
21
21
|
</div>
|
|
@@ -20,13 +20,13 @@ const { items = [] } = defineProps<ForumBreadcrumbProps>()
|
|
|
20
20
|
@if(item.link)
|
|
21
21
|
<a
|
|
22
22
|
href="{{ item.link }}"
|
|
23
|
-
class="font-medium text-gray-700
|
|
23
|
+
class="text-sm font-medium text-gray-700 hover:text-blue-600 {{ loop.index > 0 ? 'ml-1' : '' }}"
|
|
24
24
|
>
|
|
25
25
|
{{ item.label }}
|
|
26
26
|
</a>
|
|
27
27
|
@else
|
|
28
28
|
<span
|
|
29
|
-
class="font-medium text-gray-500
|
|
29
|
+
class="text-sm font-medium text-gray-500 {{ loop.index > 0 ? 'ml-1' : '' }}"
|
|
30
30
|
>
|
|
31
31
|
{{ item.label }}
|
|
32
32
|
</span>
|
|
@@ -13,7 +13,7 @@ const { title = '', description = '', link = '', topicCount = 0, postCount = 0,
|
|
|
13
13
|
</script>
|
|
14
14
|
<div class="flex items-start p-4 hover:bg-gray-50">
|
|
15
15
|
<div class="flex-shrink-0 mr-4">
|
|
16
|
-
<div class="
|
|
16
|
+
<div class="{{ icon }} w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center text-gray-500"></div>
|
|
17
17
|
</div>
|
|
18
18
|
|
|
19
19
|
<div class="flex-grow min-w-0">
|
|
@@ -19,10 +19,10 @@ function isActiveRoute(currentRoute, targetRoute) {
|
|
|
19
19
|
</div>
|
|
20
20
|
</div>
|
|
21
21
|
<nav class="flex gap-1 text-sm">
|
|
22
|
-
<a href="/forum" class="px-3 py-2
|
|
23
|
-
<a href="/forum?filter=popular" class="px-3 py-2
|
|
24
|
-
<a href="/forum?filter=recent" class="px-3 py-2
|
|
25
|
-
<a href="/forum?filter=solved" class="px-3 py-2
|
|
22
|
+
<a href="/forum" class="px-3 py-2 {{ isActiveRoute(route, 'forum') ? 'bg-gray-100 rounded-md font-medium' : 'hover:bg-gray-100 rounded-md' }}">All Discussions</a>
|
|
23
|
+
<a href="/forum?filter=popular" class="px-3 py-2 {{ isActiveRoute(route, 'forum-popular') ? 'bg-gray-100 rounded-md font-medium' : 'hover:bg-gray-100 rounded-md' }}">Popular</a>
|
|
24
|
+
<a href="/forum?filter=recent" class="px-3 py-2 {{ isActiveRoute(route, 'forum-recent') ? 'bg-gray-100 rounded-md font-medium' : 'hover:bg-gray-100 rounded-md' }}">Recent</a>
|
|
25
|
+
<a href="/forum?filter=solved" class="px-3 py-2 {{ isActiveRoute(route, 'forum-solved') ? 'bg-gray-100 rounded-md font-medium' : 'hover:bg-gray-100 rounded-md' }}">Solved</a>
|
|
26
26
|
</nav>
|
|
27
27
|
</header>
|
|
28
28
|
|
|
@@ -11,7 +11,7 @@ const { currentPage = 1, totalPages = 1, pages = [] } = defineProps<ForumPaginat
|
|
|
11
11
|
<nav class="flex gap-1 items-center">
|
|
12
12
|
<a
|
|
13
13
|
href="#"
|
|
14
|
-
class="flex items-center justify-center
|
|
14
|
+
class="w-10 h-10 flex items-center justify-center rounded-md border hover:bg-gray-100 {{ currentPage == 1 ? 'opacity-50 cursor-not-allowed' : '' }}"
|
|
15
15
|
data-action="prev-page"
|
|
16
16
|
>
|
|
17
17
|
<span class="i-hugeicons-arrow-left"></span>
|
|
@@ -20,7 +20,7 @@ const { currentPage = 1, totalPages = 1, pages = [] } = defineProps<ForumPaginat
|
|
|
20
20
|
@foreach(pages as page)
|
|
21
21
|
<a
|
|
22
22
|
href="#"
|
|
23
|
-
class="flex items-center justify-center
|
|
23
|
+
class="w-10 h-10 flex items-center justify-center rounded-md {{ currentPage == page ? 'bg-primary text-white' : 'border hover:bg-gray-100' }}"
|
|
24
24
|
data-action="go-to-page"
|
|
25
25
|
data-page="{{ page }}"
|
|
26
26
|
>
|
|
@@ -30,7 +30,7 @@ const { currentPage = 1, totalPages = 1, pages = [] } = defineProps<ForumPaginat
|
|
|
30
30
|
|
|
31
31
|
<a
|
|
32
32
|
href="#"
|
|
33
|
-
class="flex items-center justify-center
|
|
33
|
+
class="w-10 h-10 flex items-center justify-center rounded-md border hover:bg-gray-100 {{ currentPage == totalPages ? 'opacity-50 cursor-not-allowed' : '' }}"
|
|
34
34
|
data-action="next-page"
|
|
35
35
|
>
|
|
36
36
|
<span class="i-hugeicons-arrow-right"></span>
|
|
@@ -64,7 +64,7 @@ function canSubmit(content) {
|
|
|
64
64
|
Preview
|
|
65
65
|
</button>
|
|
66
66
|
<button
|
|
67
|
-
class="px-4 py-2 text-white
|
|
67
|
+
class="px-4 py-2 bg-primary text-white rounded-md hover:opacity-90 {{ canSubmit(replyContent) ? '' : 'opacity-50 cursor-not-allowed' }}"
|
|
68
68
|
data-action="submit-reply"
|
|
69
69
|
{{ canSubmit(replyContent) ? '' : 'disabled' }}
|
|
70
70
|
>
|
|
@@ -14,13 +14,13 @@ name: '',
|
|
|
14
14
|
icon: ''
|
|
15
15
|
}
|
|
16
16
|
</script>
|
|
17
|
-
<div class="
|
|
18
|
-
<div class="w-9 rounded-lg
|
|
17
|
+
<div class="{{ className }} {{ !isActive ? 'opacity-75 hover:opacity-100' : '' }}">
|
|
18
|
+
<div class="w-9 rounded-lg {{ isActive ? 'bg-blue-600' : 'bg-slate-500' }}">
|
|
19
19
|
<svg aria-hidden="true" class="h-9 w-9" fill="none">
|
|
20
20
|
<!-- feature.icon -->
|
|
21
21
|
</svg>
|
|
22
22
|
</div>
|
|
23
|
-
<h3 class="mt-6 font-medium
|
|
23
|
+
<h3 class="mt-6 text-sm font-medium {{ isActive ? 'text-blue-600' : 'text-slate-600' }}">
|
|
24
24
|
{{ feature.name }}
|
|
25
25
|
</h3>
|
|
26
26
|
<p class="mt-2 font-display text-slate-900 text-xl">
|
|
@@ -12,16 +12,16 @@ const { type = 'text', label = '', className = '', id = '', name = '', placehold
|
|
|
12
12
|
|
|
13
13
|
const formClasses = 'block w-full appearance-none rounded-md border border-gray-200 bg-gray-50 px-3 py-2 text-gray-900 placeholder-gray-400 focus:border-blue-500 focus:bg-white focus:outline-none focus:ring-blue-500 sm:text-sm'
|
|
14
14
|
</script>
|
|
15
|
-
<div class="{{ }}
|
|
15
|
+
<div class="{{ className }}">
|
|
16
16
|
@if(label)
|
|
17
17
|
<label for="{{ id }}" class="block mb-3 font-medium text-gray-700 text-sm">
|
|
18
18
|
{{ label }}
|
|
19
19
|
</label>
|
|
20
20
|
@endif
|
|
21
21
|
@if(type == 'text' || type == 'email' || type == 'password')
|
|
22
|
-
<input id="{{ id }}" type="{{ type }}" name="{{ name }}" placeholder="{{ placeholder }}" class="{{ }}
|
|
22
|
+
<input id="{{ id }}" type="{{ type }}" name="{{ name }}" placeholder="{{ placeholder }}" class="{{ formClasses }}">
|
|
23
23
|
@else
|
|
24
|
-
<select id="{{ id }}" name="{{ name }}" class="
|
|
24
|
+
<select id="{{ id }}" name="{{ name }}" class="{{ formClasses }} pr-8">
|
|
25
25
|
<slot />
|
|
26
26
|
</select>
|
|
27
27
|
@endif
|
|
@@ -18,7 +18,7 @@ subsets: ['latin'],
|
|
|
18
18
|
</script>
|
|
19
19
|
<html
|
|
20
20
|
lang="en"
|
|
21
|
-
class="h-full
|
|
21
|
+
class="h-full scroll-smooth bg-white antialiased {{ inter.variable }} {{ lexend.variable }}"
|
|
22
22
|
>
|
|
23
23
|
<body class="flex flex-col h-full">
|
|
24
24
|
<slot />
|
|
@@ -11,12 +11,12 @@ interface PlanProps {
|
|
|
11
11
|
const { name = '', price = '', description = '', href = '', features = [], featured = false } = defineProps<PlanProps>()
|
|
12
12
|
</script>
|
|
13
13
|
<section
|
|
14
|
-
class="flex
|
|
14
|
+
class="flex flex-col rounded-3xl px-6 sm:px-8 {{ featured ? 'order-first bg-blue-600 py-8 lg:order-none' : 'lg:py-8' }}"
|
|
15
15
|
>
|
|
16
16
|
<h3 class="mt-5 font-display text-lg text-white">
|
|
17
17
|
{{ name }}
|
|
18
18
|
</h3>
|
|
19
|
-
<p class="mt-2 text-base
|
|
19
|
+
<p class="mt-2 text-base {{ featured ? 'text-white' : 'text-slate-400' }}">
|
|
20
20
|
{{ description }}
|
|
21
21
|
</p>
|
|
22
22
|
<p class="order-first font-display font-light text-5xl text-white tracking-tight">
|
|
@@ -24,18 +24,18 @@ const { name = '', price = '', description = '', href = '', features = [], featu
|
|
|
24
24
|
</p>
|
|
25
25
|
<ul
|
|
26
26
|
role="list"
|
|
27
|
-
class="
|
|
27
|
+
class="order-last mt-10 flex flex-col gap-y-3 text-sm {{ featured ? 'text-white' : 'text-slate-200' }}"
|
|
28
28
|
>
|
|
29
29
|
@foreach(features as feature)
|
|
30
30
|
<li class="flex">
|
|
31
|
-
<span class="h-5 w-5
|
|
31
|
+
<span class="i-hugeicons-checkmark-circle-02 h-5 w-5 {{ featured ? 'text-white' : 'text-slate-400' }}"></span>
|
|
32
32
|
<span class="ml-4">{{ feature }}</span>
|
|
33
33
|
</li>
|
|
34
34
|
@endforeach
|
|
35
35
|
</ul>
|
|
36
36
|
<a
|
|
37
37
|
href="{{ href }}"
|
|
38
|
-
class="inline-flex items-center justify-center
|
|
38
|
+
class="mt-8 inline-flex items-center justify-center rounded-full py-2 px-4 text-sm font-semibold focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 {{ featured ? 'bg-white text-slate-900 hover:bg-blue-50 active:bg-blue-200 active:text-slate-600 focus-visible:outline-white' : 'ring-1 ring-slate-700 text-white hover:ring-slate-500 active:ring-slate-700 active:text-slate-400 focus-visible:outline-white' }}"
|
|
39
39
|
aria-label="Get started with the {{ name }} plan for {{ price }}"
|
|
40
40
|
>
|
|
41
41
|
Get started
|
|
@@ -84,12 +84,12 @@ const { plans = [ } = defineProps<PricingProps>()
|
|
|
84
84
|
<div class="grid gap-y-10 grid-cols-1 lg:grid-cols-3 xl:gap-x-8 -mx-4 mt-16 sm:mx-auto lg:-mx-8 xl:mx-0 max-w-2xl lg:max-w-none">
|
|
85
85
|
@foreach(plans as plan)
|
|
86
86
|
<section
|
|
87
|
-
class="flex
|
|
87
|
+
class="flex flex-col rounded-3xl px-6 sm:px-8 {{ plan.featured ? 'order-first bg-blue-600 py-8 lg:order-none' : 'lg:py-8' }}"
|
|
88
88
|
>
|
|
89
89
|
<h3 class="mt-5 font-display text-lg text-white">
|
|
90
90
|
{{ plan.name }}
|
|
91
91
|
</h3>
|
|
92
|
-
<p class="mt-2 text-base
|
|
92
|
+
<p class="mt-2 text-base {{ plan.featured ? 'text-white' : 'text-slate-400' }}">
|
|
93
93
|
{{ plan.description }}
|
|
94
94
|
</p>
|
|
95
95
|
<p class="order-first font-display font-light text-5xl text-white tracking-tight">
|
|
@@ -97,18 +97,18 @@ const { plans = [ } = defineProps<PricingProps>()
|
|
|
97
97
|
</p>
|
|
98
98
|
<ul
|
|
99
99
|
role="list"
|
|
100
|
-
class="
|
|
100
|
+
class="order-last mt-10 flex flex-col gap-y-3 text-sm {{ plan.featured ? 'text-white' : 'text-slate-200' }}"
|
|
101
101
|
>
|
|
102
102
|
@foreach(plan.features as feature)
|
|
103
103
|
<li class="flex">
|
|
104
|
-
<span class="h-5 w-5
|
|
104
|
+
<span class="i-hugeicons-checkmark-circle-02 h-5 w-5 {{ plan.featured ? 'text-white' : 'text-slate-400' }}"></span>
|
|
105
105
|
<span class="ml-4">{{ feature }}</span>
|
|
106
106
|
</li>
|
|
107
107
|
@endforeach
|
|
108
108
|
</ul>
|
|
109
109
|
<a
|
|
110
110
|
href="{{ plan.href }}"
|
|
111
|
-
class="inline-flex items-center justify-center
|
|
111
|
+
class="mt-8 inline-flex items-center justify-center rounded-full py-2 px-4 text-sm font-semibold focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 {{ plan.featured ? 'bg-white text-slate-900 hover:bg-blue-50' : 'ring-1 ring-slate-700 text-white hover:ring-slate-500' }}"
|
|
112
112
|
aria-label="Get started with the {{ plan.name }} plan for {{ plan.price }}"
|
|
113
113
|
>
|
|
114
114
|
Get started
|
|
@@ -44,14 +44,14 @@ const { features = [, selectedIndex = 0 } = defineProps<PrimaryFeaturesProps>()
|
|
|
44
44
|
<div class="flex overflow-x-auto sm:overflow-visible lg:col-span-5 -mx-4 mt-16 pb-4 sm:mx-0 sm:pb-0">
|
|
45
45
|
<div class="flex lg:block relative z-10 gap-x-4 lg:gap-x-0 lg:gap-y-1 px-4 sm:mx-auto sm:px-0 lg:mx-0 whitespace-nowrap lg:whitespace-normal">
|
|
46
46
|
@foreach(features as feature)
|
|
47
|
-
<div class="relative px-4 py-1 lg:
|
|
47
|
+
<div class="group relative rounded-full px-4 py-1 lg:rounded-l-xl lg:rounded-r-none lg:p-6 {{ loop.index == selectedIndex ? 'bg-white lg:bg-white/10 lg:ring-1 lg:ring-inset lg:ring-white/10' : 'hover:bg-white/10 lg:hover:bg-white/5' }}">
|
|
48
48
|
<h3>
|
|
49
|
-
<button class="font-display text-lg
|
|
49
|
+
<button class="font-display text-lg {{ loop.index == selectedIndex ? 'text-blue-600 lg:text-white' : 'text-blue-100 hover:text-white lg:text-white' }}" data-action="select-tab" data-index="{{ loop.index }}">
|
|
50
50
|
<span class="absolute inset-0 rounded-full lg:rounded-l-xl lg:rounded-r-none"></span>
|
|
51
51
|
{{ feature.title }}
|
|
52
52
|
</button>
|
|
53
53
|
</h3>
|
|
54
|
-
<p class="
|
|
54
|
+
<p class="mt-2 hidden text-sm lg:block {{ loop.index == selectedIndex ? 'text-white' : 'text-blue-100 group-hover:text-white' }}">
|
|
55
55
|
{{ feature.description }}
|
|
56
56
|
</p>
|
|
57
57
|
</div>
|
|
@@ -62,7 +62,7 @@ const { features = [, selectedIndex = 0 } = defineProps<PrimaryFeaturesProps>()
|
|
|
62
62
|
<!-- Tab Panels -->
|
|
63
63
|
<div class="lg:col-span-7">
|
|
64
64
|
@foreach(features as feature)
|
|
65
|
-
<div class="
|
|
65
|
+
<div class="{{ loop.index != selectedIndex ? 'hidden' : '' }}">
|
|
66
66
|
<div class="lg:hidden relative sm:px-6">
|
|
67
67
|
<div class="absolute bottom-[-4.25rem] top-[-6.5rem] sm:inset-x-0 bg-white/10 ring-1 ring-inset ring-white/10 sm:rounded-t-xl -inset-x-4"></div>
|
|
68
68
|
<p class="relative mx-auto max-w-2xl text-base text-white sm:text-center">
|
|
@@ -58,15 +58,15 @@ const { backgroundImage = '/images/screenshots/background-features.jpg', screens
|
|
|
58
58
|
<div class="flex overflow-x-auto sm:overflow-visible lg:col-span-5 -mx-4 pb-4 sm:mx-0 sm:pb-0">
|
|
59
59
|
<div class="flex lg:block relative z-10 gap-x-4 lg:gap-x-0 lg:gap-y-1 px-4 sm:mx-auto sm:px-0 lg:mx-0 whitespace-nowrap lg:whitespace-normal">
|
|
60
60
|
@foreach(features as feature)
|
|
61
|
-
<div class="relative px-4 py-1 lg:
|
|
61
|
+
<div class="group relative rounded-full px-4 py-1 lg:rounded-l-xl lg:rounded-r-none lg:p-6 {{ loop.index == selectedIndex ? 'bg-white lg:bg-white/10 lg:ring-1 lg:ring-inset lg:ring-white/10' : 'hover:bg-white/10 lg:hover:bg-white/5' }}">
|
|
62
62
|
<h3>
|
|
63
|
-
<button class="font-display text-lg
|
|
63
|
+
<button class="font-display text-lg {{ loop.index == selectedIndex ? 'text-blue-600 lg:text-white' : 'text-blue-100 hover:text-white lg:text-white' }}" data-action="select-tab" data-index="{{ loop.index }}">
|
|
64
64
|
<span class="absolute inset-0 rounded-full lg:rounded-l-xl lg:rounded-r-none"></span>
|
|
65
65
|
{{ feature.title }}
|
|
66
66
|
</button>
|
|
67
67
|
</h3>
|
|
68
68
|
@if(tabOrientation == 'vertical')
|
|
69
|
-
<p class="
|
|
69
|
+
<p class="mt-2 hidden text-sm lg:block {{ loop.index == selectedIndex ? 'text-white' : 'text-blue-100 group-hover:text-white' }}">
|
|
70
70
|
{{ feature.description }}
|
|
71
71
|
</p>
|
|
72
72
|
@endif
|
|
@@ -77,7 +77,7 @@ const { backgroundImage = '/images/screenshots/background-features.jpg', screens
|
|
|
77
77
|
|
|
78
78
|
<div class="lg:col-span-7">
|
|
79
79
|
@foreach(features as feature)
|
|
80
|
-
<div class="
|
|
80
|
+
<div class="{{ loop.index != selectedIndex ? 'hidden' : '' }}">
|
|
81
81
|
<div class="lg:hidden relative sm:px-6">
|
|
82
82
|
<div class="absolute bottom-[-4.25rem] top-[-6.5rem] sm:inset-x-0 bg-white/10 ring-1 ring-inset ring-white/10 sm:rounded-t-xl -inset-x-4"></div>
|
|
83
83
|
<p class="relative mx-auto max-w-2xl text-base text-white sm:text-center">
|
|
@@ -45,12 +45,12 @@ const { features = [, selectedIndex = 0 } = defineProps<SecondaryFeaturesProps>(
|
|
|
45
45
|
<div class="grid gap-x-8 grid-cols-3 pt-12">
|
|
46
46
|
@foreach(features as feature)
|
|
47
47
|
<div class="relative">
|
|
48
|
-
<div class="w-9 rounded-lg selectedIndex
|
|
48
|
+
<div class="w-9 rounded-lg {{ loop.index == selectedIndex ? 'bg-blue-600' : 'bg-slate-500' }}">
|
|
49
49
|
<svg aria-hidden="true" class="h-9 w-9" fill="none">
|
|
50
50
|
{{ feature.icon }}
|
|
51
51
|
</svg>
|
|
52
52
|
</div>
|
|
53
|
-
<h3 class="mt-6 font-medium
|
|
53
|
+
<h3 class="mt-6 text-sm font-medium {{ loop.index == selectedIndex ? 'text-blue-600' : 'text-slate-600' }}">
|
|
54
54
|
<button data-action="select-feature" data-index="{{ loop.index }}">{{ feature.name }}</button>
|
|
55
55
|
</h3>
|
|
56
56
|
<p class="mt-2 font-display text-slate-900 text-xl">
|
|
@@ -66,7 +66,7 @@ const { features = [, selectedIndex = 0 } = defineProps<SecondaryFeaturesProps>(
|
|
|
66
66
|
<div class="overflow-hidden relative mt-20 px-14 py-16 xl:px-16 bg-slate-200 rounded-4xl">
|
|
67
67
|
<div class="flex -mx-5">
|
|
68
68
|
@foreach(features as feature)
|
|
69
|
-
<div class="px-5 duration-500 ease-in-out
|
|
69
|
+
<div class="px-5 transition duration-500 ease-in-out {{ loop.index != selectedIndex ? 'opacity-60' : '' }}" style="transform: translateX(-{{ selectedIndex * 100 }}%)">
|
|
70
70
|
<div class="overflow-hidden w-[52.75rem] bg-white ring-1 ring-slate-500/10 rounded-xl shadow-lg shadow-slate-900/5">
|
|
71
71
|
<img class="w-full" src="{{ feature.image }}" alt="" sizes="52.75rem">
|
|
72
72
|
</div>
|
package/views/[...all].stx
CHANGED
|
@@ -209,7 +209,7 @@ html[data-appearance="arc"] body {
|
|
|
209
209
|
|
|
210
210
|
html[data-appearance="arc"] [data-stx-content] {
|
|
211
211
|
/* Only three margins. `margin-left` is deliberately left to the base rule.
|
|
212
|
-
|
|
212
|
+
|
|
213
213
|
It is the one margin that transitions (0.3s, for the sidebar collapse),
|
|
214
214
|
and overriding a transitioned longhand with a `calc()` over two custom
|
|
215
215
|
properties wedges the interpolation in WebKit: switching appearance leaves
|
|
@@ -217,7 +217,7 @@ html[data-appearance="arc"] [data-stx-content] {
|
|
|
217
217
|
means the property never changes when the appearance does, so there is
|
|
218
218
|
nothing to wedge — and the collapse animation keeps working identically in
|
|
219
219
|
both styles.
|
|
220
|
-
|
|
220
|
+
|
|
221
221
|
The panel strip down the card's left side is the sidebar's own trailing
|
|
222
222
|
padding, which is where it comes from in Arc too. */
|
|
223
223
|
margin-top: var(--dash-arc-gap);
|