storyloco 1.9.3 → 1.11.0
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/README.md +4 -1
- package/package.json +7 -2
- package/packages/input/types.ts +145 -0
- package/packages/shared/dist/components/ui/checkbox/checkbox.svelte +36 -0
- package/packages/shared/dist/components/ui/checkbox/checkbox.svelte.d.ts +4 -0
- package/packages/shared/dist/components/ui/checkbox/index.d.ts +2 -0
- package/packages/shared/dist/components/ui/checkbox/index.js +4 -0
- package/packages/shared/dist/components/ui/radio-group/index.d.ts +3 -0
- package/packages/shared/dist/components/ui/radio-group/index.js +5 -0
- package/packages/shared/dist/components/ui/radio-group/radio-group-item.svelte +31 -0
- package/packages/shared/dist/components/ui/radio-group/radio-group-item.svelte.d.ts +4 -0
- package/packages/shared/dist/components/ui/radio-group/radio-group.svelte +19 -0
- package/packages/shared/dist/components/ui/radio-group/radio-group.svelte.d.ts +4 -0
- package/packages/shared/dist/components/ui/textarea/index.d.ts +2 -0
- package/packages/shared/dist/components/ui/textarea/index.js +4 -0
- package/packages/shared/dist/components/ui/textarea/textarea.svelte +22 -0
- package/packages/shared/dist/components/ui/textarea/textarea.svelte.d.ts +5 -0
- package/packages/shared/dist/index.d.ts +3 -0
- package/packages/shared/dist/index.js +3 -0
- package/packages/shared/dist/utils.js +0 -1
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ A collection of slick Storyblok field plugins built with Svelte 5, TypeScript, a
|
|
|
11
11
|
- **🎨 Theme** - Color theme selector with visual previews
|
|
12
12
|
- **🔗 Link** - Link editor with support for internal, external, email, and asset links
|
|
13
13
|
- **🏗️ Plans** - Floor plan manager with drag-and-drop sorting for types, floors, dimensions, and rooms
|
|
14
|
+
- **📝 Input** - Comprehensive form input field with support for all HTML input types, checkboxes, radio buttons, selects, and textareas
|
|
14
15
|
|
|
15
16
|
### Vite Plugins
|
|
16
17
|
|
|
@@ -40,9 +41,10 @@ bun add storyloco
|
|
|
40
41
|
import type { Video } from 'storyloco/mux'
|
|
41
42
|
import type { Heading } from 'storyloco/heading'
|
|
42
43
|
import type { Link } from 'storyloco/link'
|
|
44
|
+
import type { Input } from 'storyloco/input'
|
|
43
45
|
|
|
44
46
|
// Or import everything
|
|
45
|
-
import type { Video, Heading, Link } from 'storyloco'
|
|
47
|
+
import type { Video, Heading, Link, Input } from 'storyloco'
|
|
46
48
|
```
|
|
47
49
|
|
|
48
50
|
### Use Shared Components
|
|
@@ -117,6 +119,7 @@ storyloco/
|
|
|
117
119
|
│ ├── heading/ # Heading editor plugin
|
|
118
120
|
│ ├── theme/ # Theme selector plugin
|
|
119
121
|
│ ├── link/ # Link editor plugin
|
|
122
|
+
│ ├── input/ # Form input field plugin
|
|
120
123
|
│ └── shared/ # UI component library
|
|
121
124
|
├── src/
|
|
122
125
|
│ └── index.ts # Type exports
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storyloco",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "A collection of slick Storyblok field plugins built with Svelte 5, TypeScript, and Tailwind CSS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storyblok",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"packages/theme/types.ts",
|
|
28
28
|
"packages/shared/dist",
|
|
29
29
|
"packages/vite/dist",
|
|
30
|
-
"packages/ticketsource/types.ts"
|
|
30
|
+
"packages/ticketsource/types.ts",
|
|
31
|
+
"packages/input/types.ts"
|
|
31
32
|
],
|
|
32
33
|
"exports": {
|
|
33
34
|
".": {
|
|
@@ -47,6 +48,10 @@
|
|
|
47
48
|
"types": "./packages/ticketsource/types.ts",
|
|
48
49
|
"svelte": "./packages/ticketsource/src/app.svelte.ts"
|
|
49
50
|
},
|
|
51
|
+
"./input": {
|
|
52
|
+
"types": "./packages/input/types.ts",
|
|
53
|
+
"svelte": "./packages/input/src/app.svelte.ts"
|
|
54
|
+
},
|
|
50
55
|
"./shared": {
|
|
51
56
|
"types": "./packages/shared/dist/index.d.ts",
|
|
52
57
|
"svelte": "./packages/shared/dist/index.js"
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
const types = [
|
|
2
|
+
'text',
|
|
3
|
+
'email',
|
|
4
|
+
'number',
|
|
5
|
+
'tel',
|
|
6
|
+
'url',
|
|
7
|
+
'date',
|
|
8
|
+
'time',
|
|
9
|
+
'datetime-local',
|
|
10
|
+
'month',
|
|
11
|
+
'week',
|
|
12
|
+
'checkbox',
|
|
13
|
+
'radio',
|
|
14
|
+
'select',
|
|
15
|
+
'textarea',
|
|
16
|
+
'file',
|
|
17
|
+
'hidden',
|
|
18
|
+
] as const
|
|
19
|
+
|
|
20
|
+
namespace Input {
|
|
21
|
+
export type Type = (typeof types)[number]
|
|
22
|
+
|
|
23
|
+
export type Base = {
|
|
24
|
+
name: string
|
|
25
|
+
type: Type
|
|
26
|
+
required: boolean
|
|
27
|
+
disabled: boolean
|
|
28
|
+
value?: string
|
|
29
|
+
description?: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type Placeholderable = Base & {
|
|
33
|
+
placeholder?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type File = Base & {
|
|
37
|
+
type: 'file'
|
|
38
|
+
multiple: boolean
|
|
39
|
+
accept?: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type Select = Placeholderable & {
|
|
43
|
+
type: 'select'
|
|
44
|
+
options: Array<{ value: string; disabled: boolean; selected: boolean }>
|
|
45
|
+
multiple: boolean
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type Checkbox = Omit<Base, 'required' | 'disabled'> & {
|
|
49
|
+
type: 'checkbox'
|
|
50
|
+
options: Array<{ value: string; required: boolean; disabled: boolean; checked: boolean }>
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type Radio = Base & {
|
|
54
|
+
type: 'radio'
|
|
55
|
+
options: Array<{ value: string; disabled: boolean; checked: boolean }>
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type Text = Placeholderable & {
|
|
59
|
+
type: 'text'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type Email = Placeholderable & {
|
|
63
|
+
type: 'email'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type Number = Placeholderable & {
|
|
67
|
+
type: 'number'
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type Tel = Placeholderable & {
|
|
71
|
+
type: 'tel'
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export type URL = Placeholderable & {
|
|
75
|
+
type: 'url'
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type Date = Placeholderable & {
|
|
79
|
+
type: 'date'
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type Time = Placeholderable & {
|
|
83
|
+
type: 'time'
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export type DatetimeLocal = Placeholderable & {
|
|
87
|
+
type: 'datetime-local'
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type Month = Placeholderable & {
|
|
91
|
+
type: 'month'
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type Week = Placeholderable & {
|
|
95
|
+
type: 'week'
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type Textarea = Placeholderable & {
|
|
99
|
+
type: 'textarea'
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type Hidden = Base & {
|
|
103
|
+
type: 'hidden'
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export type Input =
|
|
107
|
+
| File
|
|
108
|
+
| Select
|
|
109
|
+
| Checkbox
|
|
110
|
+
| Radio
|
|
111
|
+
| Text
|
|
112
|
+
| Email
|
|
113
|
+
| Number
|
|
114
|
+
| Tel
|
|
115
|
+
| URL
|
|
116
|
+
| Date
|
|
117
|
+
| Time
|
|
118
|
+
| DatetimeLocal
|
|
119
|
+
| Month
|
|
120
|
+
| Week
|
|
121
|
+
| Textarea
|
|
122
|
+
| Hidden
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export const types_map = new Map<Input.Type, string>([
|
|
126
|
+
['text', 'Text'],
|
|
127
|
+
['email', 'Email'],
|
|
128
|
+
['number', 'Number'],
|
|
129
|
+
['tel', 'Telephone'],
|
|
130
|
+
['url', 'URL'],
|
|
131
|
+
['date', 'Date'],
|
|
132
|
+
['time', 'Time'],
|
|
133
|
+
['datetime-local', 'Datetime Local'],
|
|
134
|
+
['month', 'Month'],
|
|
135
|
+
['week', 'Week'],
|
|
136
|
+
['checkbox', 'Checkbox'],
|
|
137
|
+
['radio', 'Radio'],
|
|
138
|
+
['select', 'Select'],
|
|
139
|
+
['textarea', 'Textarea'],
|
|
140
|
+
['file', 'File'],
|
|
141
|
+
['hidden', 'Hidden'],
|
|
142
|
+
] as const)
|
|
143
|
+
|
|
144
|
+
// convenient re-export to keep existing imports working
|
|
145
|
+
export type Input = Input.Input
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Checkbox as CheckboxPrimitive } from "bits-ui";
|
|
3
|
+
import CheckIcon from "@lucide/svelte/icons/check";
|
|
4
|
+
import MinusIcon from "@lucide/svelte/icons/minus";
|
|
5
|
+
import { cn, type WithoutChildrenOrChild } from "../../../utils.js";
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
ref = $bindable(null),
|
|
9
|
+
checked = $bindable(false),
|
|
10
|
+
indeterminate = $bindable(false),
|
|
11
|
+
class: className,
|
|
12
|
+
...restProps
|
|
13
|
+
}: WithoutChildrenOrChild<CheckboxPrimitive.RootProps> = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<CheckboxPrimitive.Root
|
|
17
|
+
bind:ref
|
|
18
|
+
data-slot="checkbox"
|
|
19
|
+
class={cn(
|
|
20
|
+
"border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive shadow-xs peer flex size-4 shrink-0 items-center justify-center rounded-[4px] border outline-none transition-shadow focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
21
|
+
className
|
|
22
|
+
)}
|
|
23
|
+
bind:checked
|
|
24
|
+
bind:indeterminate
|
|
25
|
+
{...restProps}
|
|
26
|
+
>
|
|
27
|
+
{#snippet children({ checked, indeterminate })}
|
|
28
|
+
<div data-slot="checkbox-indicator" class="text-current transition-none">
|
|
29
|
+
{#if checked}
|
|
30
|
+
<CheckIcon class="size-3.5" />
|
|
31
|
+
{:else if indeterminate}
|
|
32
|
+
<MinusIcon class="size-3.5" />
|
|
33
|
+
{/if}
|
|
34
|
+
</div>
|
|
35
|
+
{/snippet}
|
|
36
|
+
</CheckboxPrimitive.Root>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Checkbox as CheckboxPrimitive } from "bits-ui";
|
|
2
|
+
declare const Checkbox: import("svelte").Component<Omit<Omit<CheckboxPrimitive.RootProps, "child">, "children">, {}, "ref" | "checked" | "indeterminate">;
|
|
3
|
+
type Checkbox = ReturnType<typeof Checkbox>;
|
|
4
|
+
export default Checkbox;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
|
|
3
|
+
import CircleIcon from "@lucide/svelte/icons/circle";
|
|
4
|
+
import { cn, type WithoutChildrenOrChild } from "../../../utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: WithoutChildrenOrChild<RadioGroupPrimitive.ItemProps> = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<RadioGroupPrimitive.Item
|
|
14
|
+
bind:ref
|
|
15
|
+
data-slot="radio-group-item"
|
|
16
|
+
class={cn(
|
|
17
|
+
"border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 shadow-xs aspect-square size-4 shrink-0 rounded-full border outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
{...restProps}
|
|
21
|
+
>
|
|
22
|
+
{#snippet children({ checked })}
|
|
23
|
+
<div data-slot="radio-group-indicator" class="relative flex items-center justify-center">
|
|
24
|
+
{#if checked}
|
|
25
|
+
<CircleIcon
|
|
26
|
+
class="fill-primary absolute left-1/2 top-1/2 size-2 -translate-x-1/2 -translate-y-1/2"
|
|
27
|
+
/>
|
|
28
|
+
{/if}
|
|
29
|
+
</div>
|
|
30
|
+
{/snippet}
|
|
31
|
+
</RadioGroupPrimitive.Item>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
|
|
2
|
+
declare const RadioGroupItem: import("svelte").Component<Omit<Omit<RadioGroupPrimitive.ItemProps, "child">, "children">, {}, "ref">;
|
|
3
|
+
type RadioGroupItem = ReturnType<typeof RadioGroupItem>;
|
|
4
|
+
export default RadioGroupItem;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
|
|
3
|
+
import { cn } from "../../../utils.js";
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
ref = $bindable(null),
|
|
7
|
+
class: className,
|
|
8
|
+
value = $bindable(""),
|
|
9
|
+
...restProps
|
|
10
|
+
}: RadioGroupPrimitive.RootProps = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<RadioGroupPrimitive.Root
|
|
14
|
+
bind:ref
|
|
15
|
+
bind:value
|
|
16
|
+
data-slot="radio-group"
|
|
17
|
+
class={cn("grid gap-3", className)}
|
|
18
|
+
{...restProps}
|
|
19
|
+
/>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn, type WithElementRef, type WithoutChildren } from '../../../utils.js'
|
|
3
|
+
import type { HTMLTextareaAttributes } from 'svelte/elements'
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
ref = $bindable(null),
|
|
7
|
+
value = $bindable(),
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: WithoutChildren<WithElementRef<HTMLTextareaAttributes>> = $props()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<textarea
|
|
14
|
+
bind:this={ref}
|
|
15
|
+
data-slot="textarea"
|
|
16
|
+
class={cn(
|
|
17
|
+
'border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input-background field-sizing-content shadow-xs flex min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
bind:value
|
|
21
|
+
{...restProps}
|
|
22
|
+
></textarea>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type WithElementRef } from '../../../utils.js';
|
|
2
|
+
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
|
3
|
+
declare const Textarea: import("svelte").Component<Omit<WithElementRef<HTMLTextareaAttributes>, "children">, {}, "value" | "ref">;
|
|
4
|
+
type Textarea = ReturnType<typeof Textarea>;
|
|
5
|
+
export default Textarea;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
export * as Accordion from './components/ui/accordion/index.js';
|
|
2
2
|
export { Button } from './components/ui/button/index.js';
|
|
3
3
|
export * as Card from './components/ui/card/index.js';
|
|
4
|
+
export { Checkbox } from './components/ui/checkbox/index.js';
|
|
4
5
|
export { Input } from './components/ui/input/index.js';
|
|
5
6
|
export { Label } from './components/ui/label/index.js';
|
|
7
|
+
export * as RadioGroup from './components/ui/radio-group/index.js';
|
|
6
8
|
export * as Select from './components/ui/select/index.js';
|
|
7
9
|
export { Separator } from './components/ui/separator/index.js';
|
|
8
10
|
export { Skeleton } from './components/ui/skeleton/index.js';
|
|
9
11
|
export { Switch } from './components/ui/switch/index.js';
|
|
12
|
+
export { Textarea } from './components/ui/textarea/index.js';
|
|
10
13
|
export * as Tabs from './components/ui/tabs/index.js';
|
|
11
14
|
export { setup } from './setup.js';
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
export * as Accordion from './components/ui/accordion/index.js';
|
|
3
3
|
export { Button } from './components/ui/button/index.js';
|
|
4
4
|
export * as Card from './components/ui/card/index.js';
|
|
5
|
+
export { Checkbox } from './components/ui/checkbox/index.js';
|
|
5
6
|
export { Input } from './components/ui/input/index.js';
|
|
6
7
|
export { Label } from './components/ui/label/index.js';
|
|
8
|
+
export * as RadioGroup from './components/ui/radio-group/index.js';
|
|
7
9
|
export * as Select from './components/ui/select/index.js';
|
|
8
10
|
export { Separator } from './components/ui/separator/index.js';
|
|
9
11
|
export { Skeleton } from './components/ui/skeleton/index.js';
|
|
10
12
|
export { Switch } from './components/ui/switch/index.js';
|
|
13
|
+
export { Textarea } from './components/ui/textarea/index.js';
|
|
11
14
|
export * as Tabs from './components/ui/tabs/index.js';
|
|
12
15
|
// Global
|
|
13
16
|
export { setup } from './setup.js';
|