storyloco 1.7.0 → 1.8.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storyloco",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
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/src/app.svelte",
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,127 @@
1
+ type DateWithPrice = EventDatesResponse['data'][number] & {
2
+ price: string
3
+ }
4
+
5
+ export interface Ticketsource {
6
+ event: string
7
+ dates?: Array<{
8
+ id: string
9
+ start: string
10
+ price: string
11
+ }>
12
+ }
13
+
14
+ export interface PaginatedResponse<T> {
15
+ data: T
16
+ links: {
17
+ first: string
18
+ last: string | null
19
+ prev: string | null
20
+ next: string | null
21
+ }
22
+ meta: {
23
+ current_page: number
24
+ from: number
25
+ path: string
26
+ per_page: number
27
+ to: number
28
+ }
29
+ }
30
+
31
+ export type ListEventsResponse = PaginatedResponse<
32
+ Array<{
33
+ id: string
34
+ type: string
35
+ attributes: {
36
+ name: string
37
+ reference: string
38
+ description: string
39
+ comment: string
40
+ keywords: string
41
+ terms: string
42
+ category: string
43
+ genre: string
44
+ images: Array<{
45
+ type: string
46
+ src: string
47
+ }>
48
+ third_party_consent: {
49
+ capture: boolean
50
+ name: string
51
+ show_consent: {
52
+ email: boolean
53
+ post: boolean
54
+ sms: boolean
55
+ }
56
+ }
57
+ activated: boolean
58
+ archived: boolean
59
+ public: boolean
60
+ settled: boolean
61
+ created_at: string
62
+ updated_at: string
63
+ }
64
+ links: {
65
+ self: string
66
+ venues: string
67
+ dates: string
68
+ }
69
+ venues?: EventVenuesResponse['data']
70
+ dates?: EventDatesResponse['data']
71
+ count?: number
72
+ }>
73
+ >
74
+
75
+ export type EventVenuesResponse = PaginatedResponse<
76
+ Array<{
77
+ id: string
78
+ type: string
79
+ attributes: {
80
+ name: string
81
+ address: {
82
+ line_1: string
83
+ line_2: string
84
+ line_3: string
85
+ line_4: string
86
+ postcode: string
87
+ }
88
+ boxoffice: {
89
+ telephone: string
90
+ email: string
91
+ }
92
+ created_at: string
93
+ updated_at: any
94
+ }
95
+ links: {
96
+ self: string
97
+ dates: string
98
+ event: string
99
+ }
100
+ }>
101
+ >
102
+
103
+ export type EventDatesResponse = PaginatedResponse<
104
+ Array<{
105
+ id: string
106
+ type: string
107
+ attributes: {
108
+ doors_open: any
109
+ start: string
110
+ end: string
111
+ on_sale: boolean
112
+ on_sale_start: string
113
+ on_sale_end: string
114
+ public: boolean
115
+ cancelled: boolean
116
+ created_at: string
117
+ updated_at: string
118
+ }
119
+ links: {
120
+ self: string
121
+ book_now: string
122
+ bookings: string
123
+ event: string
124
+ venue: string
125
+ }
126
+ }>
127
+ >
@@ -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>