storyloco 1.0.2 → 1.2.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 +46 -2
- package/package.json +79 -73
- package/packages/heading/src/app.svelte +6 -6
- package/packages/mux/src/app.svelte +3 -15
- package/packages/shared/dist/components/ui/input/input.svelte +2 -2
- package/packages/shared/dist/components/ui/select/index.d.ts +11 -0
- package/packages/shared/dist/components/ui/select/index.js +14 -0
- package/packages/shared/dist/components/ui/select/select-content.svelte +40 -0
- package/packages/shared/dist/components/ui/select/select-content.svelte.d.ts +8 -0
- package/packages/shared/dist/components/ui/select/select-group-heading.svelte +21 -0
- package/packages/shared/dist/components/ui/select/select-group-heading.svelte.d.ts +10 -0
- package/packages/shared/dist/components/ui/select/select-group.svelte +7 -0
- package/packages/shared/dist/components/ui/select/select-group.svelte.d.ts +4 -0
- package/packages/shared/dist/components/ui/select/select-item.svelte +38 -0
- package/packages/shared/dist/components/ui/select/select-item.svelte.d.ts +4 -0
- package/packages/shared/dist/components/ui/select/select-label.svelte +20 -0
- package/packages/shared/dist/components/ui/select/select-label.svelte.d.ts +6 -0
- package/packages/shared/dist/components/ui/select/select-scroll-down-button.svelte +20 -0
- package/packages/shared/dist/components/ui/select/select-scroll-down-button.svelte.d.ts +4 -0
- package/packages/shared/dist/components/ui/select/select-scroll-up-button.svelte +20 -0
- package/packages/shared/dist/components/ui/select/select-scroll-up-button.svelte.d.ts +4 -0
- package/packages/shared/dist/components/ui/select/select-separator.svelte +18 -0
- package/packages/shared/dist/components/ui/select/select-separator.svelte.d.ts +4 -0
- package/packages/shared/dist/components/ui/select/select-trigger.svelte +29 -0
- package/packages/shared/dist/components/ui/select/select-trigger.svelte.d.ts +8 -0
- package/packages/shared/dist/components/ui/separator/index.d.ts +2 -0
- package/packages/shared/dist/components/ui/separator/index.js +4 -0
- package/packages/shared/dist/components/ui/separator/separator.svelte +16 -0
- package/packages/shared/dist/components/ui/separator/separator.svelte.d.ts +4 -0
- package/packages/shared/dist/index.d.ts +2 -0
- package/packages/shared/dist/index.js +2 -0
- package/packages/shared/dist/utils.js +1 -0
- package/packages/theme/src/app.svelte +2 -9
- package/packages/vite/dist/components.schema.d.ts +160 -0
- package/packages/vite/dist/components.schema.js +6 -0
- package/packages/vite/dist/components.schema.json +797 -0
- package/packages/vite/dist/index.d.ts +1 -0
- package/packages/vite/dist/index.js +2 -0
- package/packages/vite/dist/schema.plugin.d.ts +40 -0
- package/packages/vite/dist/schema.plugin.js +136 -0
- package/packages/vite/dist/shell.d.ts +14 -0
- package/packages/vite/dist/shell.js +51 -0
- package/packages/vite/dist/x.d.ts +3 -0
- package/packages/vite/dist/x.js +12 -0
- package/src/index.ts +1 -0
- package/packages/heading/README.md +0 -68
- package/packages/mux/README.md +0 -68
- package/packages/shared/README.md +0 -58
- package/packages/theme/README.md +0 -68
package/README.md
CHANGED
|
@@ -9,6 +9,11 @@ A collection of slick Storyblok field plugins built with Svelte 5, TypeScript, a
|
|
|
9
9
|
- **🎬 Mux Video** - Upload, manage, and configure videos with Mux integration
|
|
10
10
|
- **📝 Heading** - Simple heading editor with level selection (H1-H6)
|
|
11
11
|
- **🎨 Theme** - Color theme selector with visual previews
|
|
12
|
+
- **🔗 Link** - Link editor with support for internal, external, email, and asset links
|
|
13
|
+
|
|
14
|
+
### Vite Plugins
|
|
15
|
+
|
|
16
|
+
- **📋 Storyblok Schema** - Automatically generate TypeScript types from your Storyblok components
|
|
12
17
|
|
|
13
18
|
### Shared Components
|
|
14
19
|
|
|
@@ -33,18 +38,54 @@ bun add storyloco
|
|
|
33
38
|
// Import specific plugin types
|
|
34
39
|
import type { Video } from 'storyloco/mux'
|
|
35
40
|
import type { Heading } from 'storyloco/heading'
|
|
41
|
+
import type { Link } from 'storyloco/link'
|
|
36
42
|
|
|
37
43
|
// Or import everything
|
|
38
|
-
import type { Video, Heading } from 'storyloco'
|
|
44
|
+
import type { Video, Heading, Link } from 'storyloco'
|
|
39
45
|
```
|
|
40
46
|
|
|
41
47
|
### Use Shared Components
|
|
42
48
|
|
|
43
49
|
```typescript
|
|
44
|
-
import { Input, Label, Switch, Skeleton } from 'storyloco/shared'
|
|
50
|
+
import { Input, Label, Switch, Skeleton, Select, Separator } from 'storyloco/shared'
|
|
45
51
|
import { cn } from 'storyloco/shared/utils'
|
|
46
52
|
```
|
|
47
53
|
|
|
54
|
+
### Vite Plugins
|
|
55
|
+
|
|
56
|
+
#### Storyblok Schema Plugin
|
|
57
|
+
|
|
58
|
+
Automatically generate TypeScript types from your Storyblok components during development:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// vite.config.ts
|
|
62
|
+
import { storyblok_schema } from 'storyloco/vite'
|
|
63
|
+
|
|
64
|
+
export default defineConfig({
|
|
65
|
+
plugins: [
|
|
66
|
+
storyblok_schema({
|
|
67
|
+
output_path: 'src/lib/storyblok',
|
|
68
|
+
interval_ms: 60000 // regenerate every minute
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Options:**
|
|
75
|
+
|
|
76
|
+
- `storyblok_personal_access_token` - Your Storyblok personal access token (defaults to `STORYBLOK_PERSONAL_ACCESS_TOKEN` env var)
|
|
77
|
+
- `storyblok_space_id` - Your Storyblok space ID (defaults to `STORYBLOK_SPACE_ID` env var)
|
|
78
|
+
- `output_path` - Where to output generated files (defaults to `src/lib`)
|
|
79
|
+
- `interval_ms` - How often to regenerate types (defaults to 60000ms)
|
|
80
|
+
|
|
81
|
+
The plugin will:
|
|
82
|
+
|
|
83
|
+
- Pull your component schema from Storyblok
|
|
84
|
+
- Generate TypeScript definitions
|
|
85
|
+
- Format the output with Prettier
|
|
86
|
+
- Lock the generated file to prevent manual edits
|
|
87
|
+
- Regenerate automatically when components change
|
|
88
|
+
|
|
48
89
|
## 🔧 Development
|
|
49
90
|
|
|
50
91
|
### Prerequisites
|
|
@@ -74,6 +115,7 @@ storyloco/
|
|
|
74
115
|
│ ├── mux/ # Video upload & management plugin
|
|
75
116
|
│ ├── heading/ # Heading editor plugin
|
|
76
117
|
│ ├── theme/ # Theme selector plugin
|
|
118
|
+
│ ├── link/ # Link editor plugin
|
|
77
119
|
│ └── shared/ # UI component library
|
|
78
120
|
├── src/
|
|
79
121
|
│ └── index.ts # Type exports
|
|
@@ -126,6 +168,8 @@ The shared package provides a comprehensive set of UI components:
|
|
|
126
168
|
- `Input` - Text input with proper styling
|
|
127
169
|
- `Label` - Accessible form labels
|
|
128
170
|
- `Switch` - Toggle switch component
|
|
171
|
+
- `Select` - Select component
|
|
172
|
+
- `Separator` - Separator component
|
|
129
173
|
|
|
130
174
|
### Display Components
|
|
131
175
|
|
package/package.json
CHANGED
|
@@ -1,75 +1,81 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
2
|
+
"name": "storyloco",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "A collection of slick Storyblok field plugins built with Svelte 5, TypeScript, and Tailwind CSS",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"storyblok",
|
|
7
|
+
"field-plugin",
|
|
8
|
+
"svelte",
|
|
9
|
+
"typescript",
|
|
10
|
+
"tailwind",
|
|
11
|
+
"cms",
|
|
12
|
+
"headless"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/darbymanning/storyloco.git"
|
|
18
|
+
},
|
|
19
|
+
"main": "./src/index.ts",
|
|
20
|
+
"types": "./src/index.ts",
|
|
21
|
+
"files": [
|
|
22
|
+
"src",
|
|
23
|
+
"packages/mux/src/app.svelte",
|
|
24
|
+
"packages/mux/types.ts",
|
|
25
|
+
"packages/heading/src/app.svelte",
|
|
26
|
+
"packages/heading/types.ts",
|
|
27
|
+
"packages/theme/src/app.svelte",
|
|
28
|
+
"packages/shared/dist",
|
|
29
|
+
"packages/vite/dist"
|
|
30
|
+
],
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./src/index.ts",
|
|
34
|
+
"import": "./src/index.ts"
|
|
35
|
+
},
|
|
36
|
+
"./mux": {
|
|
37
|
+
"types": "./packages/mux/types.ts",
|
|
38
|
+
"import": "./packages/mux/src/app.svelte"
|
|
39
|
+
},
|
|
40
|
+
"./heading": {
|
|
41
|
+
"types": "./packages/heading/types.ts",
|
|
42
|
+
"import": "./packages/heading/src/app.svelte"
|
|
43
|
+
},
|
|
44
|
+
"./shared": {
|
|
45
|
+
"types": "./packages/shared/dist/index.d.ts",
|
|
46
|
+
"svelte": "./packages/shared/dist/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./shared/utils": {
|
|
49
|
+
"types": "./packages/shared/dist/utils.d.ts",
|
|
50
|
+
"svelte": "./packages/shared/dist/utils.js"
|
|
51
|
+
},
|
|
52
|
+
"./vite": {
|
|
53
|
+
"types": "./packages/vite/dist/index.d.ts",
|
|
54
|
+
"import": "./packages/vite/dist/index.js"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/node": "24.0.0",
|
|
59
|
+
"@typescript-eslint/eslint-plugin": "8.34.0",
|
|
60
|
+
"@typescript-eslint/parser": "8.34.0",
|
|
61
|
+
"eslint": "9.28.0",
|
|
62
|
+
"eslint-plugin-prettier": "5.4.1",
|
|
63
|
+
"kitto": "1.0.0-rc.12",
|
|
64
|
+
"prettier": "3.5.3",
|
|
65
|
+
"typescript": "5.8.3",
|
|
66
|
+
"vite": "6.3.5"
|
|
67
|
+
},
|
|
68
|
+
"scripts": {
|
|
69
|
+
"add-plugin": "npx @storyblok/field-plugin-cli@latest add --dir \"./packages\" --structure monorepo",
|
|
70
|
+
"build": "cd packages/vite && npm run build && cd ../../packages/shared && npm run build",
|
|
71
|
+
"lint": "eslint --ext .js .",
|
|
72
|
+
"format": "prettier . --write"
|
|
73
|
+
},
|
|
74
|
+
"type": "module",
|
|
75
|
+
"workspaces": [
|
|
76
|
+
"packages/*"
|
|
77
|
+
],
|
|
78
|
+
"dependencies": {
|
|
79
|
+
"color": "5.0.0"
|
|
80
|
+
}
|
|
75
81
|
}
|
|
@@ -10,22 +10,22 @@
|
|
|
10
10
|
let content: Heading = $state({ text: '', level: 1 })
|
|
11
11
|
|
|
12
12
|
onMount(() => {
|
|
13
|
-
createFieldPlugin({
|
|
13
|
+
createFieldPlugin<Heading>({
|
|
14
14
|
enablePortalModal: true,
|
|
15
15
|
validateContent: (content) => {
|
|
16
16
|
if (typeof content !== 'object' || content === null) {
|
|
17
|
-
return { content: { text: '', level: 1 }
|
|
17
|
+
return { content: { text: '', level: 1 } }
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const validated = content as Heading
|
|
21
|
+
|
|
21
22
|
// ensure level is one of the allowed values
|
|
22
23
|
if (![1, 2, 3, 4, 5, 6].includes(validated.level)) {
|
|
23
24
|
validated.level = 1
|
|
24
25
|
}
|
|
26
|
+
|
|
25
27
|
// ensure text is a string
|
|
26
|
-
if (typeof validated.text !== 'string')
|
|
27
|
-
validated.text = ''
|
|
28
|
-
}
|
|
28
|
+
if (typeof validated.text !== 'string') validated.text = ''
|
|
29
29
|
|
|
30
30
|
return { content: validated }
|
|
31
31
|
},
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
<fieldset class="flex gap-2">
|
|
47
47
|
<Input class="flex-1" bind:value={content.text} oninput={update} />
|
|
48
48
|
<select
|
|
49
|
-
class="rounded outline-none focus-visible:border-ring border-input bg-white border dark:bg-input/30"
|
|
49
|
+
class="rounded outline-none focus-visible:border-ring border-input bg-white border dark:bg-input/30 min-h-11.5"
|
|
50
50
|
bind:value={() => content.level, (v) => (content.level = Number(v) as Heading['level'])}
|
|
51
51
|
onchange={update}
|
|
52
52
|
>
|
|
@@ -22,9 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
type MuxAsset = Mux.Video.Assets.Asset
|
|
24
24
|
type Plugin = FieldPluginResponse<Video | null>
|
|
25
|
-
</script>
|
|
26
25
|
|
|
27
|
-
<script lang="ts">
|
|
28
26
|
let content: Video | null = $state(null)
|
|
29
27
|
let plugin: Plugin | null = $state(null)
|
|
30
28
|
let assets: Array<MuxAsset> | null = $state(null)
|
|
@@ -40,18 +38,8 @@
|
|
|
40
38
|
})
|
|
41
39
|
|
|
42
40
|
onMount(() => {
|
|
43
|
-
createFieldPlugin({
|
|
41
|
+
createFieldPlugin<Video>({
|
|
44
42
|
enablePortalModal: true,
|
|
45
|
-
validateContent: (c) => {
|
|
46
|
-
if (typeof c !== 'object' || c === null) {
|
|
47
|
-
return { content: null }
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Update local state
|
|
51
|
-
content = c as Video
|
|
52
|
-
|
|
53
|
-
return { content: c }
|
|
54
|
-
},
|
|
55
43
|
onUpdateState: (state) => {
|
|
56
44
|
plugin = state as Plugin
|
|
57
45
|
},
|
|
@@ -184,7 +172,7 @@
|
|
|
184
172
|
|
|
185
173
|
function date(date: string): string {
|
|
186
174
|
const d = new Date(Number(date) * 1000)
|
|
187
|
-
return format_elapse(d) || format_date('{MMM} {
|
|
175
|
+
return format_elapse(d) || format_date('{MMM} {D}, {YYYY}', d)
|
|
188
176
|
}
|
|
189
177
|
|
|
190
178
|
const is_modal_open = $derived.by(() => plugin?.type === 'loaded' && plugin.data.isModalOpen)
|
|
@@ -488,7 +476,7 @@
|
|
|
488
476
|
<div class="grid gap-2">
|
|
489
477
|
<Label for="preload">Preload</Label>
|
|
490
478
|
<select
|
|
491
|
-
class="bg-background border rounded min-h-
|
|
479
|
+
class="bg-background border rounded min-h-11.5 outline-none focus-visible:border-ring transition-colors w-full"
|
|
492
480
|
bind:value={content.preload}
|
|
493
481
|
onchange={(event) => {
|
|
494
482
|
if (!event.target || !(event.target instanceof HTMLSelectElement)) return
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
bind:this={ref}
|
|
25
25
|
data-slot="input"
|
|
26
26
|
class={cn(
|
|
27
|
-
'selection:bg-primary dark:bg-input/30 selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-
|
|
27
|
+
'selection:bg-primary dark:bg-input/30 selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-11.5 w-full min-w-0 rounded-md border bg-transparent px-3 pt-1.5 text-sm font-medium outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
|
28
28
|
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
|
|
29
29
|
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
|
|
30
30
|
classname
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
bind:this={ref}
|
|
40
40
|
data-slot="input"
|
|
41
41
|
class={cn(
|
|
42
|
-
'border-input bg-white selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-
|
|
42
|
+
'border-input bg-white selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-11.5 w-full min-w-0 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
|
43
43
|
'focus-visible:border-ring',
|
|
44
44
|
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
|
|
45
45
|
classname
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Group from "./select-group.svelte";
|
|
2
|
+
import Label from "./select-label.svelte";
|
|
3
|
+
import Item from "./select-item.svelte";
|
|
4
|
+
import Content from "./select-content.svelte";
|
|
5
|
+
import Trigger from "./select-trigger.svelte";
|
|
6
|
+
import Separator from "./select-separator.svelte";
|
|
7
|
+
import ScrollDownButton from "./select-scroll-down-button.svelte";
|
|
8
|
+
import ScrollUpButton from "./select-scroll-up-button.svelte";
|
|
9
|
+
import GroupHeading from "./select-group-heading.svelte";
|
|
10
|
+
declare const Root: import("svelte").Component<import("bits-ui").SelectRootPropsWithoutHTML, {}, "value" | "open">;
|
|
11
|
+
export { Root, Group, Label, Item, Content, Trigger, Separator, ScrollDownButton, ScrollUpButton, GroupHeading, Root as Select, Group as SelectGroup, Label as SelectLabel, Item as SelectItem, Content as SelectContent, Trigger as SelectTrigger, Separator as SelectSeparator, ScrollDownButton as SelectScrollDownButton, ScrollUpButton as SelectScrollUpButton, GroupHeading as SelectGroupHeading, };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Select as SelectPrimitive } from "bits-ui";
|
|
2
|
+
import Group from "./select-group.svelte";
|
|
3
|
+
import Label from "./select-label.svelte";
|
|
4
|
+
import Item from "./select-item.svelte";
|
|
5
|
+
import Content from "./select-content.svelte";
|
|
6
|
+
import Trigger from "./select-trigger.svelte";
|
|
7
|
+
import Separator from "./select-separator.svelte";
|
|
8
|
+
import ScrollDownButton from "./select-scroll-down-button.svelte";
|
|
9
|
+
import ScrollUpButton from "./select-scroll-up-button.svelte";
|
|
10
|
+
import GroupHeading from "./select-group-heading.svelte";
|
|
11
|
+
const Root = SelectPrimitive.Root;
|
|
12
|
+
export { Root, Group, Label, Item, Content, Trigger, Separator, ScrollDownButton, ScrollUpButton, GroupHeading,
|
|
13
|
+
//
|
|
14
|
+
Root as Select, Group as SelectGroup, Label as SelectLabel, Item as SelectItem, Content as SelectContent, Trigger as SelectTrigger, Separator as SelectSeparator, ScrollDownButton as SelectScrollDownButton, ScrollUpButton as SelectScrollUpButton, GroupHeading as SelectGroupHeading, };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Select as SelectPrimitive } from "bits-ui";
|
|
3
|
+
import SelectScrollUpButton from "./select-scroll-up-button.svelte";
|
|
4
|
+
import SelectScrollDownButton from "./select-scroll-down-button.svelte";
|
|
5
|
+
import { cn, type WithoutChild } from "../../../utils.js";
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
ref = $bindable(null),
|
|
9
|
+
class: className,
|
|
10
|
+
sideOffset = 4,
|
|
11
|
+
portalProps,
|
|
12
|
+
children,
|
|
13
|
+
...restProps
|
|
14
|
+
}: WithoutChild<SelectPrimitive.ContentProps> & {
|
|
15
|
+
portalProps?: SelectPrimitive.PortalProps;
|
|
16
|
+
} = $props();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<SelectPrimitive.Portal {...portalProps}>
|
|
20
|
+
<SelectPrimitive.Content
|
|
21
|
+
bind:ref
|
|
22
|
+
{sideOffset}
|
|
23
|
+
data-slot="select-content"
|
|
24
|
+
class={cn(
|
|
25
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-h-(--bits-select-content-available-height) origin-(--bits-select-content-transform-origin) relative z-50 min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border shadow-md data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
26
|
+
className
|
|
27
|
+
)}
|
|
28
|
+
{...restProps}
|
|
29
|
+
>
|
|
30
|
+
<SelectScrollUpButton />
|
|
31
|
+
<SelectPrimitive.Viewport
|
|
32
|
+
class={cn(
|
|
33
|
+
"h-(--bits-select-anchor-height) min-w-(--bits-select-anchor-width) w-full scroll-my-1 p-1"
|
|
34
|
+
)}
|
|
35
|
+
>
|
|
36
|
+
{@render children?.()}
|
|
37
|
+
</SelectPrimitive.Viewport>
|
|
38
|
+
<SelectScrollDownButton />
|
|
39
|
+
</SelectPrimitive.Content>
|
|
40
|
+
</SelectPrimitive.Portal>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Select as SelectPrimitive } from "bits-ui";
|
|
2
|
+
import { type WithoutChild } from "../../../utils.js";
|
|
3
|
+
type $$ComponentProps = WithoutChild<SelectPrimitive.ContentProps> & {
|
|
4
|
+
portalProps?: SelectPrimitive.PortalProps;
|
|
5
|
+
};
|
|
6
|
+
declare const SelectContent: import("svelte").Component<$$ComponentProps, {}, "ref">;
|
|
7
|
+
type SelectContent = ReturnType<typeof SelectContent>;
|
|
8
|
+
export default SelectContent;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Select as SelectPrimitive } from "bits-ui";
|
|
3
|
+
import { cn } from "../../../utils.js";
|
|
4
|
+
import type { ComponentProps } from "svelte";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
children,
|
|
10
|
+
...restProps
|
|
11
|
+
}: ComponentProps<typeof SelectPrimitive.GroupHeading> = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<SelectPrimitive.GroupHeading
|
|
15
|
+
bind:ref
|
|
16
|
+
data-slot="select-group-heading"
|
|
17
|
+
class={cn("text-muted-foreground px-2 py-1.5 text-xs", className)}
|
|
18
|
+
{...restProps}
|
|
19
|
+
>
|
|
20
|
+
{@render children?.()}
|
|
21
|
+
</SelectPrimitive.GroupHeading>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare const SelectGroupHeading: import("svelte").Component<Omit<{}, "child" | "children"> & {
|
|
2
|
+
child?: import("svelte").Snippet<[{
|
|
3
|
+
props: Record<string, unknown>;
|
|
4
|
+
}]> | undefined;
|
|
5
|
+
children?: import("svelte").Snippet<[]> | undefined;
|
|
6
|
+
style?: import("bits-ui").StyleProperties | string | null | undefined;
|
|
7
|
+
ref?: HTMLElement | null | undefined;
|
|
8
|
+
} & import("bits-ui").Without<import("bits-ui").BitsPrimitiveDivAttributes, import("bits-ui").ComboboxGroupHeadingPropsWithoutHTML>, {}, "ref">;
|
|
9
|
+
type SelectGroupHeading = ReturnType<typeof SelectGroupHeading>;
|
|
10
|
+
export default SelectGroupHeading;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import CheckIcon from "@lucide/svelte/icons/check";
|
|
3
|
+
import { Select as SelectPrimitive } from "bits-ui";
|
|
4
|
+
import { cn, type WithoutChild } from "../../../utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
value,
|
|
10
|
+
label,
|
|
11
|
+
children: childrenProp,
|
|
12
|
+
...restProps
|
|
13
|
+
}: WithoutChild<SelectPrimitive.ItemProps> = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<SelectPrimitive.Item
|
|
17
|
+
bind:ref
|
|
18
|
+
{value}
|
|
19
|
+
data-slot="select-item"
|
|
20
|
+
class={cn(
|
|
21
|
+
"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground outline-hidden *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-2 pr-8 text-sm data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
22
|
+
className
|
|
23
|
+
)}
|
|
24
|
+
{...restProps}
|
|
25
|
+
>
|
|
26
|
+
{#snippet children({ selected, highlighted })}
|
|
27
|
+
<span class="absolute right-2 flex size-3.5 items-center justify-center">
|
|
28
|
+
{#if selected}
|
|
29
|
+
<CheckIcon class="size-4" />
|
|
30
|
+
{/if}
|
|
31
|
+
</span>
|
|
32
|
+
{#if childrenProp}
|
|
33
|
+
{@render childrenProp({ selected, highlighted })}
|
|
34
|
+
{:else}
|
|
35
|
+
{label || value}
|
|
36
|
+
{/if}
|
|
37
|
+
{/snippet}
|
|
38
|
+
</SelectPrimitive.Item>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn, type WithElementRef } from "../../../utils.js";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
ref = $bindable(null),
|
|
7
|
+
class: className,
|
|
8
|
+
children,
|
|
9
|
+
...restProps
|
|
10
|
+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {} = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<div
|
|
14
|
+
bind:this={ref}
|
|
15
|
+
data-slot="select-label"
|
|
16
|
+
class={cn("text-muted-foreground px-2 py-1.5 text-xs", className)}
|
|
17
|
+
{...restProps}
|
|
18
|
+
>
|
|
19
|
+
{@render children?.()}
|
|
20
|
+
</div>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type WithElementRef } from "../../../utils.js";
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
type $$ComponentProps = WithElementRef<HTMLAttributes<HTMLDivElement>> & {};
|
|
4
|
+
declare const SelectLabel: import("svelte").Component<$$ComponentProps, {}, "ref">;
|
|
5
|
+
type SelectLabel = ReturnType<typeof SelectLabel>;
|
|
6
|
+
export default SelectLabel;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ChevronDownIcon from "@lucide/svelte/icons/chevron-down";
|
|
3
|
+
import { Select as SelectPrimitive } from "bits-ui";
|
|
4
|
+
import { cn, type WithoutChildrenOrChild } from "../../../utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: WithoutChildrenOrChild<SelectPrimitive.ScrollDownButtonProps> = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<SelectPrimitive.ScrollDownButton
|
|
14
|
+
bind:ref
|
|
15
|
+
data-slot="select-scroll-down-button"
|
|
16
|
+
class={cn("flex cursor-default items-center justify-center py-1", className)}
|
|
17
|
+
{...restProps}
|
|
18
|
+
>
|
|
19
|
+
<ChevronDownIcon class="size-4" />
|
|
20
|
+
</SelectPrimitive.ScrollDownButton>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Select as SelectPrimitive } from "bits-ui";
|
|
2
|
+
declare const SelectScrollDownButton: import("svelte").Component<Omit<Omit<SelectPrimitive.ScrollDownButtonProps, "child">, "children">, {}, "ref">;
|
|
3
|
+
type SelectScrollDownButton = ReturnType<typeof SelectScrollDownButton>;
|
|
4
|
+
export default SelectScrollDownButton;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ChevronUpIcon from "@lucide/svelte/icons/chevron-up";
|
|
3
|
+
import { Select as SelectPrimitive } from "bits-ui";
|
|
4
|
+
import { cn, type WithoutChildrenOrChild } from "../../../utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: WithoutChildrenOrChild<SelectPrimitive.ScrollUpButtonProps> = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<SelectPrimitive.ScrollUpButton
|
|
14
|
+
bind:ref
|
|
15
|
+
data-slot="select-scroll-up-button"
|
|
16
|
+
class={cn("flex cursor-default items-center justify-center py-1", className)}
|
|
17
|
+
{...restProps}
|
|
18
|
+
>
|
|
19
|
+
<ChevronUpIcon class="size-4" />
|
|
20
|
+
</SelectPrimitive.ScrollUpButton>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Select as SelectPrimitive } from "bits-ui";
|
|
2
|
+
declare const SelectScrollUpButton: import("svelte").Component<Omit<Omit<SelectPrimitive.ScrollUpButtonProps, "child">, "children">, {}, "ref">;
|
|
3
|
+
type SelectScrollUpButton = ReturnType<typeof SelectScrollUpButton>;
|
|
4
|
+
export default SelectScrollUpButton;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Separator as SeparatorPrimitive } from 'bits-ui'
|
|
3
|
+
import { Separator } from '../separator/index.js'
|
|
4
|
+
import { cn } from '../../../utils.js'
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: SeparatorPrimitive.RootProps = $props()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<Separator
|
|
14
|
+
bind:ref
|
|
15
|
+
data-slot="select-separator"
|
|
16
|
+
class={cn('bg-border pointer-events-none -mx-1 my-1 h-px', className)}
|
|
17
|
+
{...restProps}
|
|
18
|
+
/>
|