\n\n",
+ "type": "registry:ui"
+ }
+ ]
+}
diff --git a/public/r/registry.json b/public/r/registry.json
index 1949733..a5ebe7f 100644
--- a/public/r/registry.json
+++ b/public/r/registry.json
@@ -86,6 +86,34 @@
"title": "Accordion",
"description": "Collapsible panels that expand to their content height on a smooth ease, with a chevron that rotates with a springy overshoot. Pure CSS.",
"url": "https://verve.jettonn.dev/r/accordion.json"
+ },
+ {
+ "name": "tag-input",
+ "type": "registry:ui",
+ "title": "TagInput",
+ "description": "A tag field: Enter pops a pill in with a back-eased overshoot, × removes it with a scale-down fade, and Backspace clears the last. Highlights on focus-within.",
+ "url": "https://verve.jettonn.dev/r/tag-input.json"
+ },
+ {
+ "name": "pin-input",
+ "type": "registry:ui",
+ "title": "PinInput",
+ "description": "A one-time-code field of single-character boxes. Each digit pops in with a back-eased scale and advances focus; Backspace in an empty box steps back. Emits a complete event.",
+ "url": "https://verve.jettonn.dev/r/pin-input.json"
+ },
+ {
+ "name": "ripple-button",
+ "type": "registry:ui",
+ "title": "RippleButton",
+ "description": "A button with a material-style ripple that starts at the exact click point, scaling out and fading over 0.6s inside an overflow-hidden face.",
+ "url": "https://verve.jettonn.dev/r/ripple-button.json"
+ },
+ {
+ "name": "marquee",
+ "type": "registry:ui",
+ "title": "Marquee",
+ "description": "An infinite horizontal chip loop that pauses on hover, with edge mask fades. The list is duplicated and slid translateX 0 to -50% for a seamless loop. Pure CSS.",
+ "url": "https://verve.jettonn.dev/r/marquee.json"
}
]
}
diff --git a/public/r/ripple-button.json b/public/r/ripple-button.json
new file mode 100644
index 0000000..cd9176d
--- /dev/null
+++ b/public/r/ripple-button.json
@@ -0,0 +1,16 @@
+{
+ "$schema": "https://shadcn-vue.com/schema/registry-item.json",
+ "name": "ripple-button",
+ "type": "registry:ui",
+ "title": "RippleButton",
+ "description": "A button with a material-style ripple that starts at the exact click point, scaling out and fading over 0.6s inside an overflow-hidden face.",
+ "dependencies": ["motion-v@^2.3.0"],
+ "registryDependencies": ["https://verve.jettonn.dev/r/use-reduced-motion.json"],
+ "files": [
+ {
+ "path": "ui/RippleButton.vue",
+ "content": "\n\n\n \n\n",
+ "type": "registry:ui"
+ }
+ ]
+}
diff --git a/public/r/tag-input.json b/public/r/tag-input.json
new file mode 100644
index 0000000..7d658d6
--- /dev/null
+++ b/public/r/tag-input.json
@@ -0,0 +1,16 @@
+{
+ "$schema": "https://shadcn-vue.com/schema/registry-item.json",
+ "name": "tag-input",
+ "type": "registry:ui",
+ "title": "TagInput",
+ "description": "A tag field: Enter pops a pill in with a back-eased overshoot, × removes it with a scale-down fade, and Backspace clears the last. Highlights on focus-within.",
+ "dependencies": ["motion-v@^2.3.0", "lucide-vue-next"],
+ "registryDependencies": ["https://verve.jettonn.dev/r/use-reduced-motion.json"],
+ "files": [
+ {
+ "path": "ui/TagInput.vue",
+ "content": "\n\n\n \n
\n \n \n {{ tag.label }}\n \n \n \n\n \n
\n\n",
+ "type": "registry:ui"
+ }
+ ]
+}
diff --git a/public/r/theme-toggle.json b/public/r/theme-toggle.json
index dab4faa..892f86a 100644
--- a/public/r/theme-toggle.json
+++ b/public/r/theme-toggle.json
@@ -4,17 +4,12 @@
"type": "registry:ui",
"title": "ThemeToggle",
"description": "Day/night switch: the knob springs across while sun and moon cross-fade with a blurred scale.",
- "dependencies": [
- "motion-v@^2.3.0",
- "lucide-vue-next"
- ],
- "registryDependencies": [
- "https://verve.jettonn.dev/r/use-reduced-motion.json"
- ],
+ "dependencies": ["motion-v@^2.3.0", "lucide-vue-next"],
+ "registryDependencies": ["https://verve.jettonn.dev/r/use-reduced-motion.json"],
"files": [
{
"path": "ui/ThemeToggle.vue",
- "content": "\n\n\n \n\n",
+ "content": "\n\n\n \n\n",
"type": "registry:ui"
}
]
diff --git a/registry.json b/registry.json
index 5f7c957..2a13bf5 100644
--- a/registry.json
+++ b/registry.json
@@ -107,6 +107,40 @@
"description": "Collapsible panels that expand to their content height on a smooth ease, with a chevron that rotates with a springy overshoot. Pure CSS.",
"dependencies": ["lucide-vue-next"],
"files": [{ "path": "src/components/Accordion.vue", "type": "registry:ui" }]
+ },
+ {
+ "name": "tag-input",
+ "type": "registry:ui",
+ "title": "TagInput",
+ "description": "A tag field: Enter pops a pill in with a back-eased overshoot, × removes it with a scale-down fade, and Backspace clears the last. Highlights on focus-within.",
+ "dependencies": ["motion-v@^2.3.0", "lucide-vue-next"],
+ "registryDependencies": ["use-reduced-motion"],
+ "files": [{ "path": "src/components/TagInput.vue", "type": "registry:ui" }]
+ },
+ {
+ "name": "pin-input",
+ "type": "registry:ui",
+ "title": "PinInput",
+ "description": "A one-time-code field of single-character boxes. Each digit pops in with a back-eased scale and advances focus; Backspace in an empty box steps back. Emits a complete event.",
+ "dependencies": ["motion-v@^2.3.0"],
+ "registryDependencies": ["use-reduced-motion"],
+ "files": [{ "path": "src/components/PinInput.vue", "type": "registry:ui" }]
+ },
+ {
+ "name": "ripple-button",
+ "type": "registry:ui",
+ "title": "RippleButton",
+ "description": "A button with a material-style ripple that starts at the exact click point, scaling out and fading over 0.6s inside an overflow-hidden face.",
+ "dependencies": ["motion-v@^2.3.0"],
+ "registryDependencies": ["use-reduced-motion"],
+ "files": [{ "path": "src/components/RippleButton.vue", "type": "registry:ui" }]
+ },
+ {
+ "name": "marquee",
+ "type": "registry:ui",
+ "title": "Marquee",
+ "description": "An infinite horizontal chip loop that pauses on hover, with edge mask fades. The list is duplicated and slid translateX 0 to -50% for a seamless loop. Pure CSS.",
+ "files": [{ "path": "src/components/Marquee.vue", "type": "registry:ui" }]
}
]
}
diff --git a/src/App.vue b/src/App.vue
index 102874c..a5e49a2 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -16,7 +16,11 @@ import {
AnimatedCounter,
StaggeredList,
ErrorShake,
- Accordion
+ Accordion,
+ TagInput,
+ PinInput,
+ RippleButton,
+ Marquee
} from './components'
// Raw sources for the copy-to-clipboard buttons.
@@ -31,6 +35,10 @@ import CounterSrc from './components/AnimatedCounter.vue?raw'
import StaggeredSrc from './components/StaggeredList.vue?raw'
import ErrorShakeSrc from './components/ErrorShake.vue?raw'
import AccordionSrc from './components/Accordion.vue?raw'
+import TagInputSrc from './components/TagInput.vue?raw'
+import PinInputSrc from './components/PinInput.vue?raw'
+import RippleButtonSrc from './components/RippleButton.vue?raw'
+import MarqueeSrc from './components/Marquee.vue?raw'
// Will resolve once the repo is pushed under the active account.
const repoUrl = 'https://github.com/Jettonn/verve'
@@ -86,6 +94,18 @@ const accordionItems = [
}
]
const shakeRef = ref | null>(null)
+const tags = ref(['Vue', 'Motion'])
+const pin = ref('')
+const marqueeChips = [
+ 'Spring',
+ 'Stagger',
+ 'Ripple',
+ 'Tooltip',
+ 'Magnetic',
+ 'Tween',
+ 'Blur',
+ 'Overshoot'
+]
const demoBtn =
'interactive rounded-full border border-foreground/10 bg-foreground/[0.04] px-3 py-1.5 text-xs font-medium tracking-tight text-foreground hover:bg-foreground/[0.07]'
@@ -295,6 +315,30 @@ const demoBtn =
>
+
+
+
+
+
+
+
+
+
+
+ Press anywhere
+
+
+
+
+
diff --git a/src/components/Marquee.vue b/src/components/Marquee.vue
new file mode 100644
index 0000000..112b6db
--- /dev/null
+++ b/src/components/Marquee.vue
@@ -0,0 +1,77 @@
+
+
+
+