storyloco 1.8.0 → 1.8.2
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/package.json +7 -3
- package/packages/ticketsource/types.ts +123 -0
- package/packages/theme/src/app.svelte +0 -142
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storyloco",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.2",
|
|
4
4
|
"description": "A collection of slick Storyblok field plugins built with Svelte 5, TypeScript, and Tailwind CSS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storyblok",
|
|
@@ -24,9 +24,10 @@
|
|
|
24
24
|
"packages/heading/types.ts",
|
|
25
25
|
"packages/plans/types.ts",
|
|
26
26
|
"packages/link/types.ts",
|
|
27
|
-
"packages/theme/
|
|
27
|
+
"packages/theme/types.ts",
|
|
28
28
|
"packages/shared/dist",
|
|
29
|
-
"packages/vite/dist"
|
|
29
|
+
"packages/vite/dist",
|
|
30
|
+
"packages/ticketsource/types.ts"
|
|
30
31
|
],
|
|
31
32
|
"exports": {
|
|
32
33
|
".": {
|
|
@@ -42,6 +43,9 @@
|
|
|
42
43
|
"./plans": {
|
|
43
44
|
"types": "./packages/plans/types.ts"
|
|
44
45
|
},
|
|
46
|
+
"./ticketsource": {
|
|
47
|
+
"types": "./packages/ticketsource/types.ts"
|
|
48
|
+
},
|
|
45
49
|
"./shared": {
|
|
46
50
|
"types": "./packages/shared/dist/index.d.ts",
|
|
47
51
|
"svelte": "./packages/shared/dist/index.js"
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
export interface Ticketsource {
|
|
2
|
+
event: string
|
|
3
|
+
dates: Array<{
|
|
4
|
+
id: string
|
|
5
|
+
start: string
|
|
6
|
+
price: string
|
|
7
|
+
}>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface PaginatedResponse<T> {
|
|
11
|
+
data: T
|
|
12
|
+
links: {
|
|
13
|
+
first: string
|
|
14
|
+
last: string | null
|
|
15
|
+
prev: string | null
|
|
16
|
+
next: string | null
|
|
17
|
+
}
|
|
18
|
+
meta: {
|
|
19
|
+
current_page: number
|
|
20
|
+
from: number
|
|
21
|
+
path: string
|
|
22
|
+
per_page: number
|
|
23
|
+
to: number
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type ListEventsResponse = PaginatedResponse<
|
|
28
|
+
Array<{
|
|
29
|
+
id: string
|
|
30
|
+
type: string
|
|
31
|
+
attributes: {
|
|
32
|
+
name: string
|
|
33
|
+
reference: string
|
|
34
|
+
description: string
|
|
35
|
+
comment: string
|
|
36
|
+
keywords: string
|
|
37
|
+
terms: string
|
|
38
|
+
category: string
|
|
39
|
+
genre: string
|
|
40
|
+
images: Array<{
|
|
41
|
+
type: string
|
|
42
|
+
src: string
|
|
43
|
+
}>
|
|
44
|
+
third_party_consent: {
|
|
45
|
+
capture: boolean
|
|
46
|
+
name: string
|
|
47
|
+
show_consent: {
|
|
48
|
+
email: boolean
|
|
49
|
+
post: boolean
|
|
50
|
+
sms: boolean
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
activated: boolean
|
|
54
|
+
archived: boolean
|
|
55
|
+
public: boolean
|
|
56
|
+
settled: boolean
|
|
57
|
+
created_at: string
|
|
58
|
+
updated_at: string
|
|
59
|
+
}
|
|
60
|
+
links: {
|
|
61
|
+
self: string
|
|
62
|
+
venues: string
|
|
63
|
+
dates: string
|
|
64
|
+
}
|
|
65
|
+
venues?: EventVenuesResponse['data']
|
|
66
|
+
dates?: EventDatesResponse['data']
|
|
67
|
+
count?: number
|
|
68
|
+
}>
|
|
69
|
+
>
|
|
70
|
+
|
|
71
|
+
export type EventVenuesResponse = PaginatedResponse<
|
|
72
|
+
Array<{
|
|
73
|
+
id: string
|
|
74
|
+
type: string
|
|
75
|
+
attributes: {
|
|
76
|
+
name: string
|
|
77
|
+
address: {
|
|
78
|
+
line_1: string
|
|
79
|
+
line_2: string
|
|
80
|
+
line_3: string
|
|
81
|
+
line_4: string
|
|
82
|
+
postcode: string
|
|
83
|
+
}
|
|
84
|
+
boxoffice: {
|
|
85
|
+
telephone: string
|
|
86
|
+
email: string
|
|
87
|
+
}
|
|
88
|
+
created_at: string
|
|
89
|
+
updated_at: any
|
|
90
|
+
}
|
|
91
|
+
links: {
|
|
92
|
+
self: string
|
|
93
|
+
dates: string
|
|
94
|
+
event: string
|
|
95
|
+
}
|
|
96
|
+
}>
|
|
97
|
+
>
|
|
98
|
+
|
|
99
|
+
export type EventDatesResponse = PaginatedResponse<
|
|
100
|
+
Array<{
|
|
101
|
+
id: string
|
|
102
|
+
type: string
|
|
103
|
+
attributes: {
|
|
104
|
+
doors_open: any
|
|
105
|
+
start: string
|
|
106
|
+
end: string
|
|
107
|
+
on_sale: boolean
|
|
108
|
+
on_sale_start: string
|
|
109
|
+
on_sale_end: string
|
|
110
|
+
public: boolean
|
|
111
|
+
cancelled: boolean
|
|
112
|
+
created_at: string
|
|
113
|
+
updated_at: string
|
|
114
|
+
}
|
|
115
|
+
links: {
|
|
116
|
+
self: string
|
|
117
|
+
book_now: string
|
|
118
|
+
bookings: string
|
|
119
|
+
event: string
|
|
120
|
+
venue: string
|
|
121
|
+
}
|
|
122
|
+
}>
|
|
123
|
+
>
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { createFieldPlugin, type FieldPluginResponse } from '@storyblok/field-plugin'
|
|
3
|
-
import { onMount } from 'svelte'
|
|
4
|
-
import { dash } from 'radashi'
|
|
5
|
-
import { ChevronDownIcon } from '@lucide/svelte'
|
|
6
|
-
import { cn } from 'shared/utils'
|
|
7
|
-
import { slide } from 'svelte/transition'
|
|
8
|
-
|
|
9
|
-
type Theme = {
|
|
10
|
-
name: string
|
|
11
|
-
primary: string
|
|
12
|
-
value: string
|
|
13
|
-
secondary?: string
|
|
14
|
-
tertiary?: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
type Plugin = FieldPluginResponse<Content>
|
|
18
|
-
type Content = string | null
|
|
19
|
-
|
|
20
|
-
let plugin: Plugin | null = $state(null)
|
|
21
|
-
let content: Content = $state(null)
|
|
22
|
-
let open = $state(false)
|
|
23
|
-
|
|
24
|
-
onMount(() => {
|
|
25
|
-
createFieldPlugin<Content>({
|
|
26
|
-
validateContent(content) {
|
|
27
|
-
if (typeof content !== 'string' || content === 'none') {
|
|
28
|
-
return { content: null }
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return { content }
|
|
32
|
-
},
|
|
33
|
-
onUpdateState(state) {
|
|
34
|
-
plugin = state as Plugin
|
|
35
|
-
if (plugin?.type === 'loaded') content = plugin.data.content
|
|
36
|
-
},
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
function update() {
|
|
41
|
-
if (plugin?.type !== 'loaded') return
|
|
42
|
-
const state = $state.snapshot(content)
|
|
43
|
-
plugin.actions.setContent(state === 'none' ? null : state)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const themes: Array<Theme> = $derived.by(() => {
|
|
47
|
-
if (plugin?.type !== 'loaded') return []
|
|
48
|
-
|
|
49
|
-
return Object.entries(plugin.data.options).map(([key, value]) => {
|
|
50
|
-
const [primary, secondary, tertiary] = value.split(',')
|
|
51
|
-
return {
|
|
52
|
-
name: key,
|
|
53
|
-
value: `theme-${dash(key)}`,
|
|
54
|
-
primary,
|
|
55
|
-
secondary,
|
|
56
|
-
tertiary,
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
const selected = $derived.by(() => {
|
|
62
|
-
if (plugin?.type !== 'loaded') return
|
|
63
|
-
|
|
64
|
-
return themes.find((theme) => theme.value === content)
|
|
65
|
-
})
|
|
66
|
-
</script>
|
|
67
|
-
|
|
68
|
-
<div class="@container">
|
|
69
|
-
{#if themes?.length}
|
|
70
|
-
<button
|
|
71
|
-
class="border border-input rounded p-1 px-3.5 bg-input-background min-h-11.5 text-start outline-none focus-visible:border-ring flex items-center justify-between w-full hover:border-primary"
|
|
72
|
-
onclick={() => (open = !open)}
|
|
73
|
-
>
|
|
74
|
-
<span class:text-muted-foreground={!selected}>{selected?.name || 'Select a theme…'}</span>
|
|
75
|
-
<ChevronDownIcon size={16} class={cn({ 'rotate-180': open }, 'transition-transform')} />
|
|
76
|
-
</button>
|
|
77
|
-
{#if open}
|
|
78
|
-
<fieldset
|
|
79
|
-
class="bg-input-background border border-input rounded grid @[220px]:grid-cols-2 @sm:grid-cols-3 divide-y mt-1 overflow-hidden p-3 gap-3 max-h-120 overflow-y-auto"
|
|
80
|
-
transition:slide
|
|
81
|
-
>
|
|
82
|
-
{#each themes as { value, name, primary, secondary, tertiary }, index}
|
|
83
|
-
{#snippet Label(value: string)}
|
|
84
|
-
<input
|
|
85
|
-
class={cn(
|
|
86
|
-
'sr-only',
|
|
87
|
-
`
|
|
88
|
-
dark:[&:checked+label]:text-background
|
|
89
|
-
[&:checked+label]:border-primary
|
|
90
|
-
[&:checked+label]:bg-white
|
|
91
|
-
|
|
92
|
-
focus-visible:[&:checked+label]:outline-primary
|
|
93
|
-
focus-visible:[&:checked+label]:outline-2
|
|
94
|
-
focus-visible:[&:checked+label]:outline-offset-2
|
|
95
|
-
`,
|
|
96
|
-
{
|
|
97
|
-
'dark:[&:checked+label_figure_span]:border-background': value === 'none',
|
|
98
|
-
}
|
|
99
|
-
)}
|
|
100
|
-
id={value}
|
|
101
|
-
type="radio"
|
|
102
|
-
value={value === 'none' ? null : value}
|
|
103
|
-
bind:group={content}
|
|
104
|
-
onchange={update}
|
|
105
|
-
/>
|
|
106
|
-
<label
|
|
107
|
-
for={value}
|
|
108
|
-
class="grid text-xs text-center items-center gap-2 p-3 border rounded relative cursor-pointer justify-center hover:bg-primary/10 border-input bg-secondary hover:border-primary transition-colors"
|
|
109
|
-
>
|
|
110
|
-
<figure
|
|
111
|
-
class={cn(
|
|
112
|
-
'flex justify-center [&>span]:size-10 @xl:[&>span]:size-12 [&>span]:border-white [&>span]:rounded-full [&>span]:border-2 [&>span:not(:first-child)]:-ml-[25%] [&>span]:relative isolate m-auto',
|
|
113
|
-
{ '[&>span]:border-foreground': value === 'none' }
|
|
114
|
-
)}
|
|
115
|
-
>
|
|
116
|
-
{#if value === 'none'}
|
|
117
|
-
<span></span>
|
|
118
|
-
{:else}
|
|
119
|
-
<span class="z-30" title={primary} style="background-color: {primary}"></span>
|
|
120
|
-
{#if secondary}
|
|
121
|
-
<span class="z-10" title={secondary} style="background-color: {secondary}"
|
|
122
|
-
></span>
|
|
123
|
-
{/if}
|
|
124
|
-
{#if tertiary}
|
|
125
|
-
<span class="z-10" title={tertiary} style="background-color: {tertiary}"></span>
|
|
126
|
-
{/if}
|
|
127
|
-
{/if}
|
|
128
|
-
</figure>
|
|
129
|
-
<span class="truncate" title={value}>
|
|
130
|
-
{value === 'none' ? 'Default' : name}
|
|
131
|
-
</span>
|
|
132
|
-
</label>
|
|
133
|
-
{/snippet}
|
|
134
|
-
{#if index === 0}
|
|
135
|
-
{@render Label('none')}
|
|
136
|
-
{/if}
|
|
137
|
-
{@render Label(value)}
|
|
138
|
-
{/each}
|
|
139
|
-
</fieldset>
|
|
140
|
-
{/if}
|
|
141
|
-
{/if}
|
|
142
|
-
</div>
|