diff --git a/.changeset/data-slot-one.md b/.changeset/data-slot-one.md
new file mode 100644
index 000000000..5f5a877b7
--- /dev/null
+++ b/.changeset/data-slot-one.md
@@ -0,0 +1,22 @@
+---
+"fulldev-ui": minor
+---
+
+Upgrade all Data Slot primitives and registry dependencies to 1.0.1. Use recommended
+lazy mounting for Select, Tooltip, Hover Card and Navigation Menu, with an explicit
+mountStrategy="eager" opt-in for integrations that query closed content. Discover nested
+comboboxes and hover cards in retained content without duplicate initialization.
+
+Release outgoing controllers on Astro page swaps so open overlays cannot leave stale
+modal stacks or scroll locks. Give CommandDialog a trigger slot and correct the
+sidebar search composition for strict nested ownership.
+
+Use native autofocus for command palettes and native link activation for keyboard
+commands. Align Slider defaults and Tabs values with the upstream API, and make
+block dropdown links actual accessible menu items.
+
+Use shadcn button defaults and consistent overlay layers so nested popups receive
+pointer input. Form submissions should explicitly set type="submit".
+
+Keep Data Slot modal stack layers and place floating positioners above them so
+Select and other popups remain clickable inside dialogs.
diff --git a/package.json b/package.json
index 40df64235..a0977a461 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,7 @@
"stop": "lsof -tiTCP:4321 -sTCP:LISTEN | xargs kill 2>/dev/null || true",
"preview": "pnpm stop && pnpm build && astro preview --host 127.0.0.1 --port 4321",
"typecheck": "astro check",
+ "test:interactions": "playwright test --config playwright.interactions.config.ts",
"check": "pnpm format:check && pnpm typecheck",
"build": "astro build",
"build:prod": "pnpm check && pnpm registry:build && pnpm build",
@@ -72,24 +73,24 @@
"dependencies": {
"@astrojs/mdx": "^5.0.6",
"@astrojs/sitemap": "^3.7.3",
- "@data-slot/accordion": "^0.2.166",
- "@data-slot/alert-dialog": "^0.2.166",
- "@data-slot/collapsible": "^0.2.166",
- "@data-slot/combobox": "^0.2.166",
- "@data-slot/command": "^0.2.166",
- "@data-slot/core": "^0.2.166",
- "@data-slot/dialog": "^0.2.166",
- "@data-slot/dropdown-menu": "^0.2.166",
- "@data-slot/hover-card": "^0.2.166",
- "@data-slot/navigation-menu": "^0.2.166",
- "@data-slot/popover": "^0.2.166",
- "@data-slot/radio-group": "^0.2.166",
- "@data-slot/select": "^0.2.166",
- "@data-slot/slider": "^0.2.166",
- "@data-slot/switch": "^0.2.166",
- "@data-slot/tabs": "^0.2.166",
- "@data-slot/toggle": "^0.2.166",
- "@data-slot/tooltip": "^0.2.166",
+ "@data-slot/accordion": "^1.0.1",
+ "@data-slot/alert-dialog": "^1.0.1",
+ "@data-slot/collapsible": "^1.0.1",
+ "@data-slot/combobox": "^1.0.1",
+ "@data-slot/command": "^1.0.1",
+ "@data-slot/core": "^1.0.1",
+ "@data-slot/dialog": "^1.0.1",
+ "@data-slot/dropdown-menu": "^1.0.1",
+ "@data-slot/hover-card": "^1.0.1",
+ "@data-slot/navigation-menu": "^1.0.1",
+ "@data-slot/popover": "^1.0.1",
+ "@data-slot/radio-group": "^1.0.1",
+ "@data-slot/select": "^1.0.1",
+ "@data-slot/slider": "^1.0.1",
+ "@data-slot/switch": "^1.0.1",
+ "@data-slot/tabs": "^1.0.1",
+ "@data-slot/toggle": "^1.0.1",
+ "@data-slot/tooltip": "^1.0.1",
"@fontsource-variable/geist": "^5.2.9",
"@fontsource-variable/geist-mono": "^5.2.8",
"@lexingtonthemes/seo": "^0.2.0",
diff --git a/playwright.config.ts b/playwright.config.ts
index cbfeaaac7..14a60b484 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -3,6 +3,7 @@ import { defineConfig } from "@playwright/test"
export default defineConfig({
testDir: "./tests",
+ testMatch: "visual.spec.ts",
forbidOnly: !!process.env.CI,
workers: 2,
reporter: [
diff --git a/playwright.interactions.config.ts b/playwright.interactions.config.ts
new file mode 100644
index 000000000..0c9c06cdc
--- /dev/null
+++ b/playwright.interactions.config.ts
@@ -0,0 +1,42 @@
+import { defineConfig } from "@playwright/test"
+
+import config from "./playwright.config"
+
+export default defineConfig({
+ ...config,
+ testMatch: ["data-slot.spec.ts", "clipboard.spec.ts"],
+ reporter: [["list"]],
+ use: {
+ ...config.use,
+ reducedMotion: "no-preference",
+ trace: "retain-on-failure",
+ },
+ projects: [
+ {
+ name: "chromium-desktop",
+ use: { browserName: "chromium", viewport: { width: 1440, height: 1000 } },
+ },
+ {
+ name: "chromium-mobile",
+ use: {
+ browserName: "chromium",
+ viewport: { width: 390, height: 844 },
+ isMobile: true,
+ hasTouch: true,
+ },
+ },
+ {
+ name: "webkit-desktop",
+ use: { browserName: "webkit", viewport: { width: 1440, height: 1000 } },
+ },
+ {
+ name: "webkit-mobile",
+ use: {
+ browserName: "webkit",
+ viewport: { width: 390, height: 844 },
+ isMobile: true,
+ hasTouch: true,
+ },
+ },
+ ],
+})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0cc9ac3f9..ac67d3077 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15,59 +15,59 @@ importers:
specifier: ^3.7.3
version: 3.7.3
'@data-slot/accordion':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/alert-dialog':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/collapsible':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/combobox':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/command':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/core':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/dialog':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/dropdown-menu':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/hover-card':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/navigation-menu':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/popover':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/radio-group':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/select':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/slider':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/switch':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/tabs':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/toggle':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@data-slot/tooltip':
- specifier: ^0.2.166
- version: 0.2.166
+ specifier: ^1.0.1
+ version: 1.0.1
'@fontsource-variable/geist':
specifier: ^5.2.9
version: 5.3.0
@@ -444,59 +444,59 @@ packages:
resolution: {integrity: sha512-GgcWwRCs/xPtaqlMy8qRhPnZf9vlWcWZNHAitnVQ3yk7JmSralSiq5q07yaffYE8SogtDm7zFeKccx1QNVARpw==}
engines: {node: '>= 20.12.0'}
- '@data-slot/accordion@0.2.166':
- resolution: {integrity: sha512-MViSr1Nikj5PqL8aFTQMonG/9SHXYskWK0DTc8OyUvLBg5x2mwTQVTwlPxy114ZH4BMOAYlTXpZ+XuvOrDgH9Q==}
+ '@data-slot/accordion@1.0.1':
+ resolution: {integrity: sha512-gmg671YTOia+c3zM42FAikylWLpDd84UN0/fg2JvTD821bspm8t7Du+ILX2aJlWoGZEkxk6At/aqOpMEsQMajA==}
- '@data-slot/alert-dialog@0.2.166':
- resolution: {integrity: sha512-o+ne7Yjc56hteXai6KU/KsHjY0DunpOImHgrS3+K9KEhtUNtM6UAKhkA1C2FBOvHCvasZ8qdCPeWa6wME7MiAA==}
+ '@data-slot/alert-dialog@1.0.1':
+ resolution: {integrity: sha512-+3oTGvS9gVb35XcAJZRf6yAM5P7Pb/3r9TS4t++DkX0KLSnKjJ21WG8aUS1A42qNDc+twUlqcc3CLGDxtKIl2w==}
- '@data-slot/collapsible@0.2.166':
- resolution: {integrity: sha512-C1QhlaGVkV0OhB5Xa7bj/U4SZLbtMaotgZgxoq/3FXmtFbkEzU1dvumNdYWs5+6Wnwb4Pr+KfJdxfVBN1ofT1w==}
+ '@data-slot/collapsible@1.0.1':
+ resolution: {integrity: sha512-y0ugQ7+nvB9qWYcwP4fNRew+W0MJYMa+dgqbPZLB9Ga3eGu0KLC7wfA5iGxg592rGN2xjohl5ixGNuhaWvObng==}
- '@data-slot/combobox@0.2.166':
- resolution: {integrity: sha512-BPF4WKfTFeiksrlp8kyU7g3iEuICY9EBoWzrrzDWmq8di3nDI3phAO2f42M6xG7JSNf6Rvu9K8IsXzOyZk5DXA==}
+ '@data-slot/combobox@1.0.1':
+ resolution: {integrity: sha512-GefwzKOn849DA32laG4QttII1rVdJ+I1sqTi4vAeyHhaK4DnJfJq85T563DCIR1TGTEefSsFZTzxjFlniwZgbg==}
- '@data-slot/command@0.2.166':
- resolution: {integrity: sha512-+RRwXkjspJeD7gHYgVUXxvF/CkGFJS6OvRauUNhxvbaMxdCLf3KkOinFv/RKtzRFaOEEkjpanFy/DrO9agy3Cw==}
+ '@data-slot/command@1.0.1':
+ resolution: {integrity: sha512-vkgJvBr4HjSIsILOObtzuXz2A0YujzEqfRJe0dZsbDuSnMxSTVfTk5UuDNMOB3n65Q2dEthKrSYX280x0Q/u0A==}
- '@data-slot/core@0.2.166':
- resolution: {integrity: sha512-/DuzMFIqiefdjheX5fMhaqs4YPp0/t+/pN9EgnB2jLSDk8384WkBCPGq76T/Ypb0MjVlHFiexKDnx9+k+bdcjw==}
+ '@data-slot/core@1.0.1':
+ resolution: {integrity: sha512-hR5970E+ANJoawzd2LSCxnMYl+pe0VMj1IZVWYlG1UDTS+n55QrvuITMwj35+gLOCCbABhD5IMBnIJp3aVZoJA==}
- '@data-slot/dialog@0.2.166':
- resolution: {integrity: sha512-ioMkbfCMVt4x8VrNEa0V32ncs57Q3GEVqEn+uDUBoOU6Qyv2q1ebI0IMkK/54kSeUHut7FilECGUJzuvc7TJAQ==}
+ '@data-slot/dialog@1.0.1':
+ resolution: {integrity: sha512-0xtsy0p3m4082rVK8IBgJjPcav5pXYYemj7VxfTR/1OGcqXL8wu2m05HH+fKYANEPd4iHsULjX5AWbEC9l9Z7A==}
- '@data-slot/dropdown-menu@0.2.166':
- resolution: {integrity: sha512-8U9jUWlufUmHf75+w/10GHVNDc9XjfJCjVKuBWhkFbTFq68ROCzb+g/DugI/uXxz08qZWmky4nQK9kStjlet5A==}
+ '@data-slot/dropdown-menu@1.0.1':
+ resolution: {integrity: sha512-JpB7ZXxpaOrG9rN7Q76xkBJwpToe9b1nc7QMbJpgmDbog03pfpyTUBQFhHjqOEK+sNUkabG3JfVAnGG0xwm75g==}
- '@data-slot/hover-card@0.2.166':
- resolution: {integrity: sha512-ravzEp74MzWDNY83y4nPoBpScEmzRsV1QnXS6+SB4fypUIfB7OiVwlEUQ0NfCM5CgqDFrx3nZsmUzqcJRxQKxA==}
+ '@data-slot/hover-card@1.0.1':
+ resolution: {integrity: sha512-WQMXfc6RxYmc3t7R0N/Gjz3LkLeWSJqcBQuE4c+SgM4xaVXmoFxc7PEis1BE+JlmMwbLywrGubCWQo1n05yWjg==}
- '@data-slot/navigation-menu@0.2.166':
- resolution: {integrity: sha512-1yttL2tjMFsvQ4dfNMqC6MG5yABI7DGgK2Un89NGEXAG37uPmai5/KTf+68VO9gQhhLlmUkmvokyIFBFoBkF/A==}
+ '@data-slot/navigation-menu@1.0.1':
+ resolution: {integrity: sha512-qSFqHpUN93dui/VPKYgFlHp7s9pNPrEoXofJVPFkZMHnaa9+HAmfoQbPHWn6xHfHplGF6AUIUccEOm3qtpUkZg==}
- '@data-slot/popover@0.2.166':
- resolution: {integrity: sha512-NW35Efz0oEquMec1X4y/nVxTGOYPWEkcoErN3/wtj7QqRZtpyJnQMP2rxm59+il9kvUIdUCAgtWl9CyIg55CXw==}
+ '@data-slot/popover@1.0.1':
+ resolution: {integrity: sha512-4/FhCz5w6MRhXVB8hquZO0W5uyrwNTDu/UdUsavzWfNVK9pmFt4Rc7xjK6KH/uMqIu8gvxAYAsVDaFaOFsflHA==}
- '@data-slot/radio-group@0.2.166':
- resolution: {integrity: sha512-0CDJD3e+ap2o7REO5KPj8hkB75V/d3okiCaUmg3bDo+xzOkIxJ1qnif/I4QG5rRok9QBOcDjLYoyfY2Zjm9cVg==}
+ '@data-slot/radio-group@1.0.1':
+ resolution: {integrity: sha512-HCAmwdjBHY69R/q6V1k6Xc88lzfUP4idXQoOUkWwwKqqlP2DXH2NEuk9/p0zSBXDKerY8qg8UI0Ldvff/ydnIA==}
- '@data-slot/select@0.2.166':
- resolution: {integrity: sha512-8HVsjcs9LqjXfYRfK7SiuTuZirjx5DQWbSrrdifynWOwif0C9eXYrah6FR5kla9jr2/CsaoUEBlHHVsNnosNqg==}
+ '@data-slot/select@1.0.1':
+ resolution: {integrity: sha512-megYWB6aa1OupAFmQeTiRLO0cKmXyvJvS6Tht6P/gc59ioduxGLdU1SjIZS1XVK6ejN2FfXKOgx4dSsqZLwzpA==}
- '@data-slot/slider@0.2.166':
- resolution: {integrity: sha512-VuQmb1+xn9X05vSDvaz4PIbvH23K0U1azLgwUyOeUyr8WSCxcUObTbvpEPcXyGsQQySt9GEO5bX3qYLdgaMyWA==}
+ '@data-slot/slider@1.0.1':
+ resolution: {integrity: sha512-1h41stz/cZXk2HStHgAqzH/ymaiNAg6tN51HS62WnL0m4y3MJ3OvKhXKp8hdd8PgXpg5CPxrPj5k57eVzMvF1g==}
- '@data-slot/switch@0.2.166':
- resolution: {integrity: sha512-2AipHTGEiCfCOCGjKzlo2jAJ9hEN8+YbI90PrLLG8Q71TB8kNRWSdvE6hJhRzLJI0Ymdi89bVvd/DGEN38JVtA==}
+ '@data-slot/switch@1.0.1':
+ resolution: {integrity: sha512-q5Y0vwuKTro/FbZAjf67CcFK+Bl7MZoA4TOyvPPtlIeRcNmblx1Bn1OQxwpwtAE5nObNCo7l3ily3OcssAk5pw==}
- '@data-slot/tabs@0.2.166':
- resolution: {integrity: sha512-nM+kE5IgZeyX+fUq+LUiDQrbB1F47WcLtmwTngVShsMJcjFUJPrLI8snadcWJ2xD34yi6Jeq3X7iNFjK9tYfXQ==}
+ '@data-slot/tabs@1.0.1':
+ resolution: {integrity: sha512-hnr1PJhVbX+yKEAbGgo+/ITAY/Ibegxqb6G5+IFTfukQ5zJOapxrlHr4M0ERlmAKy/nNQGs830DbI5JQbBTNaA==}
- '@data-slot/toggle@0.2.166':
- resolution: {integrity: sha512-L9ejpPH75UA8zdbr1wb3DYF/nD7h+VdyyvYgJjGzjQ6J65O5s6qn8jEbPHQPlSQwyjoHyqMWvNoU359j648+BA==}
+ '@data-slot/toggle@1.0.1':
+ resolution: {integrity: sha512-ktkHGv/E3razY5+LGXyVC9hAwnNHZkXViBE3uyWEaO4leW/0ui4le7Fepg37J6PmK4hQTqhTMDKC1Gfs1ccHTQ==}
- '@data-slot/tooltip@0.2.166':
- resolution: {integrity: sha512-tpt0oqhiMhp0AeTG23S0iW27SGrRcaUZt0h3IK7H6z/a1LwCItl+8PUqqaSaHKUKlOc4oyccES4ZxlsOxW1jvA==}
+ '@data-slot/tooltip@1.0.1':
+ resolution: {integrity: sha512-Fmv/KqjnaoreUAbOMy1QsZnwGEFTh5eVFuWtOrp/a7J6NFi2oQNyzuqq3ZTx9lVJqSuSAkjPFk+FID3RDdyVUw==}
'@dotenvx/dotenvx@1.64.0':
resolution: {integrity: sha512-6+xRpZaWuHXEqnhBjae+VmQI9Uaqw5Uzu/ScpO+W7ww9Zp3lHSNBoNjFcUxhrCyc7pRGQzyDjhKzloqrPHERiQ==}
@@ -4835,75 +4835,75 @@ snapshots:
fast-wrap-ansi: 0.2.0
sisteransi: 1.0.5
- '@data-slot/accordion@0.2.166':
+ '@data-slot/accordion@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/alert-dialog@0.2.166':
+ '@data-slot/alert-dialog@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/collapsible@0.2.166':
+ '@data-slot/collapsible@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/combobox@0.2.166':
+ '@data-slot/combobox@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/command@0.2.166':
+ '@data-slot/command@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/core@0.2.166': {}
+ '@data-slot/core@1.0.1': {}
- '@data-slot/dialog@0.2.166':
+ '@data-slot/dialog@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/dropdown-menu@0.2.166':
+ '@data-slot/dropdown-menu@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/hover-card@0.2.166':
+ '@data-slot/hover-card@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/navigation-menu@0.2.166':
+ '@data-slot/navigation-menu@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/popover@0.2.166':
+ '@data-slot/popover@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/radio-group@0.2.166':
+ '@data-slot/radio-group@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/select@0.2.166':
+ '@data-slot/select@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/slider@0.2.166':
+ '@data-slot/slider@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/switch@0.2.166':
+ '@data-slot/switch@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/tabs@0.2.166':
+ '@data-slot/tabs@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/toggle@0.2.166':
+ '@data-slot/toggle@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
- '@data-slot/tooltip@0.2.166':
+ '@data-slot/tooltip@1.0.1':
dependencies:
- '@data-slot/core': 0.2.166
+ '@data-slot/core': 1.0.1
'@dotenvx/dotenvx@1.64.0':
dependencies:
diff --git a/public/r/accordion.json b/public/r/accordion.json
index c72d0a559..1304ffd9c 100644
--- a/public/r/accordion.json
+++ b/public/r/accordion.json
@@ -4,13 +4,13 @@
"title": "Accordion",
"description": "A vertically stacked set of interactive headings that each reveal a section of content.",
"dependencies": [
- "@data-slot/accordion",
+ "@data-slot/accordion@^1.0.1",
"@lucide/astro"
],
"files": [
{
"path": "src/components/ui/accordion/accordion.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n multiple?: boolean\n defaultValue?: string | string[]\n disabled?: boolean\n orientation?: \"horizontal\" | \"vertical\"\n loopFocus?: boolean\n hiddenUntilFound?: boolean\n collapsible?: boolean\n}\n\nconst {\n class: className,\n multiple,\n defaultValue,\n disabled,\n orientation = \"vertical\",\n loopFocus,\n hiddenUntilFound,\n collapsible,\n ...props\n} = Astro.props\n\nconst serializedDefaultValue = Array.isArray(defaultValue)\n ? JSON.stringify(defaultValue)\n : defaultValue\n---\n\n
\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n multiple?: boolean\n defaultValue?: string | string[]\n disabled?: boolean\n orientation?: \"horizontal\" | \"vertical\"\n loopFocus?: boolean\n hiddenUntilFound?: boolean\n collapsible?: boolean\n}\n\nconst {\n class: className,\n multiple,\n defaultValue,\n disabled,\n orientation = \"vertical\",\n loopFocus,\n hiddenUntilFound,\n collapsible,\n ...props\n} = Astro.props\n\nconst serializedDefaultValue = Array.isArray(defaultValue)\n ? JSON.stringify(defaultValue)\n : defaultValue\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/alert-dialog.json b/public/r/alert-dialog.json
index 33e3b4c60..e0fa792c0 100644
--- a/public/r/alert-dialog.json
+++ b/public/r/alert-dialog.json
@@ -4,7 +4,7 @@
"title": "Alert Dialog",
"description": "A modal dialog for important confirmations that expects a response.",
"dependencies": [
- "@data-slot/alert-dialog"
+ "@data-slot/alert-dialog@^1.0.1"
],
"registryDependencies": [
"@fulldev/button"
@@ -12,7 +12,7 @@
"files": [
{
"path": "src/components/ui/alert-dialog/alert-dialog.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n closeOnClickOutside,\n closeOnEscape,\n lockScroll,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n closeOnClickOutside,\n closeOnEscape,\n lockScroll,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/banner.json b/public/r/banner.json
index 24175e7b7..30db587b7 100644
--- a/public/r/banner.json
+++ b/public/r/banner.json
@@ -6,10 +6,6 @@
"dependencies": [
"@lucide/astro"
],
- "registryDependencies": [
- "@fulldev/button",
- "@fulldev/dropdown-menu"
- ],
"files": [
{
"path": "src/components/ui/banner/banner.astro",
diff --git a/public/r/blocks-1.json b/public/r/blocks-1.json
index eeb6cfdd3..3b685f5c0 100644
--- a/public/r/blocks-1.json
+++ b/public/r/blocks-1.json
@@ -15,7 +15,7 @@
"files": [
{
"path": "src/components/blocks/blocks-1.astro",
- "content": "---\nimport ArrowLeft from \"@lucide/astro/icons/arrow-left\"\nimport ArrowRight from \"@lucide/astro/icons/arrow-right\"\nimport Check from \"@lucide/astro/icons/check\"\nimport ChevronDown from \"@lucide/astro/icons/chevron-down\"\nimport Copy from \"@lucide/astro/icons/copy\"\nimport ExternalLink from \"@lucide/astro/icons/external-link\"\nimport Claude from \"simple-icons-astro/Claude\"\nimport Cursor from \"simple-icons-astro/Cursor\"\nimport Markdown from \"simple-icons-astro/Markdown\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { buttonVariants } from \"@/components/ui/button/button-variants\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { SectionContainer } from \"@/components/ui/section\"\nimport {\n Typography,\n TypographyH1,\n TypographyLead,\n} from \"@/components/ui/typography\"\n\ntype Props = {\n class?: string\n title: string\n description?: string\n copyButton?: {\n id: string\n source: string\n }\n markdownUrl?: string\n previousPage?: {\n href: string\n title: string\n }\n nextPage?: {\n href: string\n title: string\n }\n labels: {\n copyMarkdown: string\n openIn: string\n openInMarkdown: string\n openInChatGPT: string\n openInClaude: string\n openInCursor: string\n pagination: {\n previous: string\n next: string\n ariaLabel: string\n }\n }\n}\n\nconst {\n class: className,\n title,\n description,\n copyButton,\n markdownUrl,\n previousPage,\n nextPage,\n labels,\n} = Astro.props\nconst showCopyButton = Boolean(copyButton)\nconst showOpenButton = Boolean(markdownUrl)\nconst showPagination = Boolean(previousPage || nextPage)\nconst assistantPrompt = markdownUrl\n ? `Read ${new URL(markdownUrl, Astro.site ?? Astro.url.origin).href}, I want to ask questions about it.`\n : \"\"\nconst openLinks = markdownUrl\n ? [\n {\n label: labels.openInMarkdown,\n href: markdownUrl,\n icon: \"markdown\",\n },\n {\n label: labels.openInChatGPT,\n href: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"chatgpt\",\n },\n {\n label: labels.openInClaude,\n href: `https://claude.ai/new?q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"claude\",\n },\n {\n label: labels.openInCursor,\n href: `https://cursor.com/link/prompt?text=${encodeURIComponent(assistantPrompt)}`,\n icon: \"cursor\",\n },\n ]\n : []\n---\n\n\n \n
\n \n \n {title}\n \n {\n description && (\n \n {description}\n \n )\n }\n
\n \n \n\n
\n \n \n\n {\n showPagination && (\n
\n {previousPage ? (\n \n \n \n {previousPage.title}\n \n \n ) : (\n
\n )}\n\n {nextPage ? (\n \n {nextPage.title} \n \n \n ) : (\n
\n )}\n \n )\n }\n
\n \n\n\n",
+ "content": "---\nimport ArrowLeft from \"@lucide/astro/icons/arrow-left\"\nimport ArrowRight from \"@lucide/astro/icons/arrow-right\"\nimport Check from \"@lucide/astro/icons/check\"\nimport ChevronDown from \"@lucide/astro/icons/chevron-down\"\nimport Copy from \"@lucide/astro/icons/copy\"\nimport ExternalLink from \"@lucide/astro/icons/external-link\"\nimport Claude from \"simple-icons-astro/Claude\"\nimport Cursor from \"simple-icons-astro/Cursor\"\nimport Markdown from \"simple-icons-astro/Markdown\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { buttonVariants } from \"@/components/ui/button/button-variants\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { SectionContainer } from \"@/components/ui/section\"\nimport {\n Typography,\n TypographyH1,\n TypographyLead,\n} from \"@/components/ui/typography\"\n\ntype Props = {\n class?: string\n title: string\n description?: string\n copyButton?: {\n id: string\n source: string\n }\n markdownUrl?: string\n previousPage?: {\n href: string\n title: string\n }\n nextPage?: {\n href: string\n title: string\n }\n labels: {\n copyMarkdown: string\n openIn: string\n openInMarkdown: string\n openInChatGPT: string\n openInClaude: string\n openInCursor: string\n pagination: {\n previous: string\n next: string\n ariaLabel: string\n }\n }\n}\n\nconst {\n class: className,\n title,\n description,\n copyButton,\n markdownUrl,\n previousPage,\n nextPage,\n labels,\n} = Astro.props\nconst showCopyButton = Boolean(copyButton)\nconst showOpenButton = Boolean(markdownUrl)\nconst showPagination = Boolean(previousPage || nextPage)\nconst assistantPrompt = markdownUrl\n ? `Read ${new URL(markdownUrl, Astro.site ?? Astro.url.origin).href}, I want to ask questions about it.`\n : \"\"\nconst openLinks = markdownUrl\n ? [\n {\n label: labels.openInMarkdown,\n href: markdownUrl,\n icon: \"markdown\",\n },\n {\n label: labels.openInChatGPT,\n href: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"chatgpt\",\n },\n {\n label: labels.openInClaude,\n href: `https://claude.ai/new?q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"claude\",\n },\n {\n label: labels.openInCursor,\n href: `https://cursor.com/link/prompt?text=${encodeURIComponent(assistantPrompt)}`,\n icon: \"cursor\",\n },\n ]\n : []\n---\n\n\n \n
\n \n \n {title}\n \n {\n description && (\n \n {description}\n \n )\n }\n
\n \n {\n showCopyButton && (\n
\n \n \n {labels.copyMarkdown} \n \n )\n }\n {\n showOpenButton && (\n
\n \n {labels.openIn} \n \n \n \n {openLinks.map((link) => (\n \n {link.icon === \"markdown\" && }\n {link.icon === \"chatgpt\" && (\n \n \n \n )}\n {link.icon === \"claude\" && }\n {link.icon === \"cursor\" && }\n {link.label} \n \n \n ))}\n \n \n )\n }\n
\n \n\n
\n \n \n\n {\n showPagination && (\n
\n {previousPage ? (\n \n \n \n {previousPage.title}\n \n \n ) : (\n
\n )}\n\n {nextPage ? (\n \n {nextPage.title} \n \n \n ) : (\n
\n )}\n \n )\n }\n
\n \n\n\n",
"type": "registry:block"
}
],
diff --git a/public/r/button.json b/public/r/button.json
index 91ea3f16b..e763548de 100644
--- a/public/r/button.json
+++ b/public/r/button.json
@@ -11,7 +11,7 @@
},
{
"path": "src/components/ui/button/button.astro",
- "content": "---\nimport type { HTMLTag, Polymorphic } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\nimport { buttonVariants, type ButtonVariantProps } from \"./button-variants\"\n\ntype Props = Polymorphic<{ as: Tag }> &\n ButtonVariantProps\n\nconst {\n as: Tag = \"href\" in Astro.props ? \"a\" : \"button\",\n class: className,\n variant,\n size,\n ...props\n} = Astro.props\n---\n\n\n \n \n",
+ "content": "---\nimport type { HTMLTag, Polymorphic } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\nimport { buttonVariants, type ButtonVariantProps } from \"./button-variants\"\n\ntype Props = Polymorphic<{ as: Tag }> &\n ButtonVariantProps\n\nconst {\n as: Tag = \"href\" in Astro.props ? \"a\" : \"button\",\n class: className,\n variant,\n size,\n ...props\n} = Astro.props\n\nconst attributes: Record = { ...props }\nif (Tag === \"button\") attributes.type ??= \"button\"\n---\n\n\n \n \n",
"type": "registry:ui"
},
{
diff --git a/public/r/collapsible.json b/public/r/collapsible.json
index 499610926..e1cc26faf 100644
--- a/public/r/collapsible.json
+++ b/public/r/collapsible.json
@@ -4,12 +4,12 @@
"title": "Collapsible",
"description": "An interactive component which expands/collapses a panel.",
"dependencies": [
- "@data-slot/collapsible"
+ "@data-slot/collapsible@^1.0.1"
],
"files": [
{
"path": "src/components/ui/collapsible/collapsible.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n hiddenUntilFound?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n hiddenUntilFound,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n hiddenUntilFound?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n hiddenUntilFound,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/combobox.json b/public/r/combobox.json
index dd913b851..779c7f22c 100644
--- a/public/r/combobox.json
+++ b/public/r/combobox.json
@@ -4,7 +4,8 @@
"title": "Combobox",
"description": "Autocomplete input with a list of suggestions.",
"dependencies": [
- "@data-slot/combobox",
+ "@data-slot/combobox@^1.0.1",
+ "@data-slot/core@^1.0.1",
"@lucide/astro"
],
"registryDependencies": [
@@ -13,12 +14,12 @@
"files": [
{
"path": "src/components/ui/combobox/combobox.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type {\n Align as ComboboxAlign,\n Side as ComboboxSide,\n} from \"@data-slot/combobox\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultValue?: string\n defaultOpen?: boolean\n placeholder?: string\n disabled?: boolean\n required?: boolean\n name?: string\n openOnFocus?: boolean\n autoHighlight?: boolean\n side?: ComboboxSide\n align?: ComboboxAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n defaultValue,\n defaultOpen,\n placeholder,\n disabled,\n required,\n name,\n openOnFocus,\n autoHighlight,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type {\n Align as ComboboxAlign,\n Side as ComboboxSide,\n} from \"@data-slot/combobox\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultValue?: string\n defaultOpen?: boolean\n placeholder?: string\n disabled?: boolean\n required?: boolean\n name?: string\n openOnFocus?: boolean\n autoHighlight?: boolean\n side?: ComboboxSide\n align?: ComboboxAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n defaultValue,\n defaultOpen,\n placeholder,\n disabled,\n required,\n name,\n openOnFocus,\n autoHighlight,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
"path": "src/components/ui/combobox/combobox-content.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type {\n Align as ComboboxAlign,\n Side as ComboboxSide,\n} from \"@data-slot/combobox\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: ComboboxSide\n align?: ComboboxAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type {\n Align as ComboboxAlign,\n Side as ComboboxSide,\n} from \"@data-slot/combobox\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: ComboboxSide\n align?: ComboboxAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/command.json b/public/r/command.json
index fc464541d..7c998ba23 100644
--- a/public/r/command.json
+++ b/public/r/command.json
@@ -4,8 +4,9 @@
"title": "Command",
"description": "Command menu for search and quick actions.",
"dependencies": [
- "@data-slot/command",
- "@lucide/astro"
+ "@data-slot/command@^1.0.1",
+ "@lucide/astro",
+ "@data-slot/core@^1.0.1"
],
"registryDependencies": [
"@fulldev/dialog"
@@ -13,12 +14,12 @@
"files": [
{
"path": "src/components/ui/command/command.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n label?: string\n defaultValue?: string\n defaultSearch?: string\n shouldFilter?: boolean\n loop?: boolean\n disablePointerSelection?: boolean\n vimBindings?: boolean\n}\n\nconst {\n class: className,\n label,\n defaultValue,\n defaultSearch,\n shouldFilter,\n loop,\n disablePointerSelection,\n vimBindings,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n label?: string\n defaultValue?: string\n defaultSearch?: string\n shouldFilter?: boolean\n loop?: boolean\n disablePointerSelection?: boolean\n vimBindings?: boolean\n}\n\nconst {\n class: className,\n label,\n defaultValue,\n defaultSearch,\n shouldFilter,\n loop,\n disablePointerSelection,\n vimBindings,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
"path": "src/components/ui/command/command-dialog.astro",
- "content": "---\nimport type { ComponentProps } from \"astro/types\"\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogTitle,\n} from \"@/components/ui/dialog\"\n\ntype Props = ComponentProps & {\n title?: string\n description?: string\n contentClass?: string\n showCloseButton?: boolean\n}\n\nconst {\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n contentClass,\n showCloseButton = false,\n ...props\n} = Astro.props\n---\n\n\n \n \n {title} \n {description} \n
\n \n \n \n",
+ "content": "---\nimport type { ComponentProps } from \"astro/types\"\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogTitle,\n} from \"@/components/ui/dialog\"\n\ntype Props = ComponentProps & {\n title?: string\n description?: string\n contentClass?: string\n showCloseButton?: boolean\n}\n\nconst {\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n contentClass,\n showCloseButton = false,\n ...props\n} = Astro.props\n---\n\n\n \n \n \n {title} \n {description} \n
\n \n \n \n",
"type": "registry:ui"
},
{
diff --git a/public/r/dialog.json b/public/r/dialog.json
index 73fce0fd3..7efc1928a 100644
--- a/public/r/dialog.json
+++ b/public/r/dialog.json
@@ -4,7 +4,7 @@
"title": "Dialog",
"description": "A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.",
"dependencies": [
- "@data-slot/dialog",
+ "@data-slot/dialog@^1.0.1",
"@lucide/astro"
],
"registryDependencies": [
@@ -13,7 +13,7 @@
"files": [
{
"path": "src/components/ui/dialog/dialog.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n lockScroll?: boolean\n alertDialog?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n closeOnClickOutside,\n closeOnEscape,\n lockScroll,\n alertDialog,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n lockScroll?: boolean\n alertDialog?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n closeOnClickOutside,\n closeOnEscape,\n lockScroll,\n alertDialog,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/doc-1.json b/public/r/doc-1.json
index 9a98563c3..c83d79bea 100644
--- a/public/r/doc-1.json
+++ b/public/r/doc-1.json
@@ -18,7 +18,7 @@
"files": [
{
"path": "src/components/blocks/doc-1.astro",
- "content": "---\nimport ArrowLeft from \"@lucide/astro/icons/arrow-left\"\nimport ArrowRight from \"@lucide/astro/icons/arrow-right\"\nimport Check from \"@lucide/astro/icons/check\"\nimport ChevronDown from \"@lucide/astro/icons/chevron-down\"\nimport Copy from \"@lucide/astro/icons/copy\"\nimport ExternalLink from \"@lucide/astro/icons/external-link\"\nimport Claude from \"simple-icons-astro/Claude\"\nimport Cursor from \"simple-icons-astro/Cursor\"\nimport Markdown from \"simple-icons-astro/Markdown\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { buttonVariants } from \"@/components/ui/button/button-variants\"\nimport {\n Card,\n CardDescription,\n CardFooter,\n CardHeader,\n} from \"@/components/ui/card\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { SectionContainer } from \"@/components/ui/section\"\nimport {\n Toc,\n TocMenu,\n TocMenuItem,\n TocMenuLink,\n TocTitle,\n} from \"@/components/ui/toc\"\nimport {\n Typography,\n TypographyH1,\n TypographyLead,\n} from \"@/components/ui/typography\"\n\ntype Props = {\n class?: string\n title: string\n description?: string\n copyButton?: {\n id: string\n source: string\n }\n markdownUrl?: string\n tocItems: {\n depth: number\n href: string\n label: string\n }[]\n callout?: {\n description: string\n button: {\n label: string\n href: string\n variant?: \"default\" | \"outline\" | \"secondary\" | \"ghost\"\n }\n }\n previousPage?: {\n href: string\n title: string\n }\n nextPage?: {\n href: string\n title: string\n }\n labels: {\n copyMarkdown: string\n openIn: string\n openInMarkdown: string\n openInChatGPT: string\n openInClaude: string\n openInCursor: string\n pagination: {\n previous: string\n next: string\n ariaLabel: string\n }\n toc: string\n }\n}\n\nconst {\n class: className,\n title,\n description,\n copyButton,\n markdownUrl,\n tocItems,\n callout,\n previousPage,\n nextPage,\n labels,\n} = Astro.props\nconst showCopyButton = Boolean(copyButton)\nconst showOpenButton = Boolean(markdownUrl)\nconst showPagination = Boolean(previousPage || nextPage)\nconst assistantPrompt = markdownUrl\n ? `Read ${new URL(markdownUrl, Astro.site ?? Astro.url.origin).href}, I want to ask questions about it.`\n : \"\"\nconst openLinks = markdownUrl\n ? [\n {\n label: labels.openInMarkdown,\n href: markdownUrl,\n icon: \"markdown\",\n },\n {\n label: labels.openInChatGPT,\n href: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"chatgpt\",\n },\n {\n label: labels.openInClaude,\n href: `https://claude.ai/new?q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"claude\",\n },\n {\n label: labels.openInCursor,\n href: `https://cursor.com/link/prompt?text=${encodeURIComponent(assistantPrompt)}`,\n icon: \"cursor\",\n },\n ]\n : []\n---\n\n\n \n
\n \n \n {title}\n \n {\n description && (\n \n {description}\n \n )\n }\n
\n \n \n\n
\n \n \n\n {\n showPagination && (\n
\n {previousPage ? (\n \n \n \n {previousPage.title}\n \n \n ) : (\n
\n )}\n\n {nextPage ? (\n \n {nextPage.title} \n \n \n ) : (\n
\n )}\n \n )\n }\n
\n\n {\n (tocItems.length > 0 || callout) && (\n \n \n {tocItems.length > 0 && (\n \n {labels.toc} \n \n {tocItems.map((item) => (\n \n \n {item.label}\n \n \n ))}\n \n \n )}\n\n {callout && (\n \n \n {callout.description} \n \n \n \n {callout.button.label}\n \n \n \n )}\n
\n \n )\n }\n \n\n\n",
+ "content": "---\nimport ArrowLeft from \"@lucide/astro/icons/arrow-left\"\nimport ArrowRight from \"@lucide/astro/icons/arrow-right\"\nimport Check from \"@lucide/astro/icons/check\"\nimport ChevronDown from \"@lucide/astro/icons/chevron-down\"\nimport Copy from \"@lucide/astro/icons/copy\"\nimport ExternalLink from \"@lucide/astro/icons/external-link\"\nimport Claude from \"simple-icons-astro/Claude\"\nimport Cursor from \"simple-icons-astro/Cursor\"\nimport Markdown from \"simple-icons-astro/Markdown\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { buttonVariants } from \"@/components/ui/button/button-variants\"\nimport {\n Card,\n CardDescription,\n CardFooter,\n CardHeader,\n} from \"@/components/ui/card\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { SectionContainer } from \"@/components/ui/section\"\nimport {\n Toc,\n TocMenu,\n TocMenuItem,\n TocMenuLink,\n TocTitle,\n} from \"@/components/ui/toc\"\nimport {\n Typography,\n TypographyH1,\n TypographyLead,\n} from \"@/components/ui/typography\"\n\ntype Props = {\n class?: string\n title: string\n description?: string\n copyButton?: {\n id: string\n source: string\n }\n markdownUrl?: string\n tocItems: {\n depth: number\n href: string\n label: string\n }[]\n callout?: {\n description: string\n button: {\n label: string\n href: string\n variant?: \"default\" | \"outline\" | \"secondary\" | \"ghost\"\n }\n }\n previousPage?: {\n href: string\n title: string\n }\n nextPage?: {\n href: string\n title: string\n }\n labels: {\n copyMarkdown: string\n openIn: string\n openInMarkdown: string\n openInChatGPT: string\n openInClaude: string\n openInCursor: string\n pagination: {\n previous: string\n next: string\n ariaLabel: string\n }\n toc: string\n }\n}\n\nconst {\n class: className,\n title,\n description,\n copyButton,\n markdownUrl,\n tocItems,\n callout,\n previousPage,\n nextPage,\n labels,\n} = Astro.props\nconst showCopyButton = Boolean(copyButton)\nconst showOpenButton = Boolean(markdownUrl)\nconst showPagination = Boolean(previousPage || nextPage)\nconst assistantPrompt = markdownUrl\n ? `Read ${new URL(markdownUrl, Astro.site ?? Astro.url.origin).href}, I want to ask questions about it.`\n : \"\"\nconst openLinks = markdownUrl\n ? [\n {\n label: labels.openInMarkdown,\n href: markdownUrl,\n icon: \"markdown\",\n },\n {\n label: labels.openInChatGPT,\n href: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"chatgpt\",\n },\n {\n label: labels.openInClaude,\n href: `https://claude.ai/new?q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"claude\",\n },\n {\n label: labels.openInCursor,\n href: `https://cursor.com/link/prompt?text=${encodeURIComponent(assistantPrompt)}`,\n icon: \"cursor\",\n },\n ]\n : []\n---\n\n\n \n
\n \n \n {title}\n \n {\n description && (\n \n {description}\n \n )\n }\n
\n \n {\n showCopyButton && (\n
\n \n \n {labels.copyMarkdown} \n \n )\n }\n {\n showOpenButton && (\n
\n \n {labels.openIn} \n \n \n \n {openLinks.map((link) => (\n \n {link.icon === \"markdown\" && }\n {link.icon === \"chatgpt\" && (\n \n \n \n )}\n {link.icon === \"claude\" && }\n {link.icon === \"cursor\" && }\n {link.label} \n \n \n ))}\n \n \n )\n }\n
\n \n\n
\n \n \n\n {\n showPagination && (\n
\n {previousPage ? (\n \n \n \n {previousPage.title}\n \n \n ) : (\n
\n )}\n\n {nextPage ? (\n \n {nextPage.title} \n \n \n ) : (\n
\n )}\n \n )\n }\n
\n\n {\n (tocItems.length > 0 || callout) && (\n \n \n {tocItems.length > 0 && (\n \n {labels.toc} \n \n {tocItems.map((item) => (\n \n \n {item.label}\n \n \n ))}\n \n \n )}\n\n {callout && (\n \n \n {callout.description} \n \n \n \n {callout.button.label}\n \n \n \n )}\n
\n \n )\n }\n \n\n\n",
"type": "registry:block"
}
],
diff --git a/public/r/dropdown-menu.json b/public/r/dropdown-menu.json
index 3d80de76e..58bba60c2 100644
--- a/public/r/dropdown-menu.json
+++ b/public/r/dropdown-menu.json
@@ -4,13 +4,13 @@
"title": "Dropdown Menu",
"description": "Displays a menu to the user, such as a set of actions or functions, triggered by a button.",
"dependencies": [
- "@data-slot/dropdown-menu",
+ "@data-slot/dropdown-menu@^1.0.1",
"@lucide/astro"
],
"files": [
{
"path": "src/components/ui/dropdown-menu/dropdown-menu.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Side } from \"@data-slot/dropdown-menu\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n defaultValue?: string | null\n defaultValues?: string[]\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n closeOnSelect?: boolean\n highlightItemOnHover?: boolean\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n defaultValue,\n defaultValues,\n closeOnClickOutside,\n closeOnEscape,\n closeOnSelect,\n highlightItemOnHover,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n lockScroll,\n ...props\n} = Astro.props\n\nconst defaultValuesAttr =\n defaultValues === undefined ? undefined : JSON.stringify(defaultValues)\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Side } from \"@data-slot/dropdown-menu\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n defaultValue?: string | null\n defaultValues?: string[]\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n closeOnSelect?: boolean\n highlightItemOnHover?: boolean\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n defaultValue,\n defaultValues,\n closeOnClickOutside,\n closeOnEscape,\n closeOnSelect,\n highlightItemOnHover,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n lockScroll,\n ...props\n} = Astro.props\n\nconst defaultValuesAttr =\n defaultValues === undefined ? undefined : JSON.stringify(defaultValues)\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
@@ -20,12 +20,12 @@
},
{
"path": "src/components/ui/dropdown-menu/dropdown-menu-content.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Side } from \"@data-slot/dropdown-menu\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Side } from \"@data-slot/dropdown-menu\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n",
"type": "registry:ui"
},
{
"path": "src/components/ui/dropdown-menu/dropdown-menu-item.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"button\"> & {\n disabled?: boolean\n variant?: \"default\" | \"destructive\"\n inset?: boolean\n}\n\nconst {\n class: className,\n type = \"button\",\n disabled,\n variant,\n inset,\n ...props\n} = Astro.props\n---\n\n\n \n \n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"button\"> &\n HTMLAttributes<\"a\"> & {\n as?: \"button\" | \"a\"\n disabled?: boolean\n variant?: \"default\" | \"destructive\"\n inset?: boolean\n }\n\nconst {\n as: Tag = \"href\" in Astro.props ? \"a\" : \"button\",\n class: className,\n type = \"button\",\n disabled,\n variant,\n inset,\n ...props\n} = Astro.props\n---\n\n\n \n \n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/hover-card.json b/public/r/hover-card.json
index 67dc7099e..e17759b5e 100644
--- a/public/r/hover-card.json
+++ b/public/r/hover-card.json
@@ -4,18 +4,18 @@
"title": "Hover Card",
"description": "For sighted users to preview content available behind a link.",
"dependencies": [
- "@data-slot/hover-card",
- "@data-slot/core"
+ "@data-slot/hover-card@^1.0.1",
+ "@data-slot/core@^1.0.1"
],
"files": [
{
"path": "src/components/ui/hover-card/hover-card.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n delay?: number\n skipDelayDuration?: number\n closeDelay?: number\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n portal?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n open,\n delay = 700,\n skipDelayDuration = 300,\n closeDelay = 300,\n side = \"bottom\",\n align = \"center\",\n sideOffset = 4,\n alignOffset = 0,\n avoidCollisions = true,\n collisionPadding = 8,\n portal = true,\n closeOnClickOutside = true,\n closeOnEscape = true,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n mountStrategy?: \"lazy\" | \"eager\"\n defaultOpen?: boolean\n open?: boolean\n delay?: number\n skipDelayDuration?: number\n closeDelay?: number\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n portal?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n}\n\nconst {\n mountStrategy,\n class: className,\n defaultOpen,\n open,\n delay = 700,\n skipDelayDuration = 300,\n closeDelay = 300,\n side = \"bottom\",\n align = \"center\",\n sideOffset = 4,\n alignOffset = 0,\n avoidCollisions = true,\n collisionPadding = 8,\n portal = true,\n closeOnClickOutside = true,\n closeOnEscape = true,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
"path": "src/components/ui/hover-card/hover-card-content.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/input-group.json b/public/r/input-group.json
index 7de218bd8..45d73590f 100644
--- a/public/r/input-group.json
+++ b/public/r/input-group.json
@@ -5,7 +5,6 @@
"description": "Add addons, buttons, and helper content to inputs.",
"registryDependencies": [
"@fulldev/button",
- "@fulldev/dropdown-menu",
"@fulldev/input",
"@fulldev/textarea"
],
diff --git a/public/r/layout.json b/public/r/layout.json
index f5717dda0..17c0bfa73 100644
--- a/public/r/layout.json
+++ b/public/r/layout.json
@@ -3,6 +3,9 @@
"name": "layout",
"title": "Layout",
"description": "Page-shell primitives for the root html, head, body, and main structure.",
+ "dependencies": [
+ "@lexingtonthemes/seo@^0.2.0"
+ ],
"files": [
{
"path": "src/components/ui/layout/layout.astro",
diff --git a/public/r/navigation-menu.json b/public/r/navigation-menu.json
index a41039a40..145ea44f9 100644
--- a/public/r/navigation-menu.json
+++ b/public/r/navigation-menu.json
@@ -4,13 +4,13 @@
"title": "Navigation Menu",
"description": "A collection of links for navigating websites.",
"dependencies": [
- "@data-slot/navigation-menu",
+ "@data-slot/navigation-menu@^1.0.1",
"@lucide/astro"
],
"files": [
{
"path": "src/components/ui/navigation-menu/navigation-menu.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\nimport NavigationMenuPositioner from \"./navigation-menu-positioner.astro\"\n\ntype Props = HTMLAttributes<\"nav\"> & {\n delayOpen?: number\n delayClose?: number\n openOnFocus?: boolean\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n positionMethod?: \"absolute\" | \"fixed\"\n safeTriangle?: boolean\n debugSafeTriangle?: boolean\n}\n\nconst {\n class: className = \"\",\n delayOpen = 0,\n delayClose = 0,\n openOnFocus,\n side = \"bottom\",\n align = \"start\",\n sideOffset = 0,\n alignOffset = 0,\n positionMethod = \"absolute\",\n safeTriangle,\n debugSafeTriangle,\n ...props\n} = Astro.props\n---\n\n\n \n \n \n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\nimport NavigationMenuPositioner from \"./navigation-menu-positioner.astro\"\n\ntype Props = HTMLAttributes<\"nav\"> & {\n mountStrategy?: \"lazy\" | \"eager\"\n delayOpen?: number\n delayClose?: number\n openOnFocus?: boolean\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n positionMethod?: \"absolute\" | \"fixed\"\n safeTriangle?: boolean\n debugSafeTriangle?: boolean\n}\n\nconst {\n mountStrategy,\n class: className = \"\",\n delayOpen = 0,\n delayClose = 0,\n openOnFocus,\n side = \"bottom\",\n align = \"start\",\n sideOffset = 0,\n alignOffset = 0,\n positionMethod = \"absolute\",\n safeTriangle,\n debugSafeTriangle,\n ...props\n} = Astro.props\n---\n\n\n \n \n \n\n\n",
"type": "registry:ui"
},
{
@@ -50,7 +50,7 @@
},
{
"path": "src/components/ui/navigation-menu/navigation-menu-positioner.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n sideOffset?: number\n align?: \"start\" | \"center\" | \"end\"\n alignOffset?: number\n}\n\nconst {\n class: className,\n side = \"bottom\",\n sideOffset = 8,\n align = \"start\",\n alignOffset = 0,\n ...props\n} = Astro.props\n---\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n sideOffset?: number\n align?: \"start\" | \"center\" | \"end\"\n alignOffset?: number\n}\n\nconst {\n class: className,\n side = \"bottom\",\n sideOffset = 8,\n align = \"start\",\n alignOffset = 0,\n ...props\n} = Astro.props\n---\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/popover.json b/public/r/popover.json
index f63bdd151..935120c9c 100644
--- a/public/r/popover.json
+++ b/public/r/popover.json
@@ -4,12 +4,12 @@
"title": "Popover",
"description": "Displays rich content in a floating layer, triggered by a button.",
"dependencies": [
- "@data-slot/popover"
+ "@data-slot/popover@^1.0.1"
],
"files": [
{
"path": "src/components/ui/popover/popover.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { PopoverAlign, PopoverSide } from \"@data-slot/popover\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n side?: PopoverSide\n align?: PopoverAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n portal?: boolean\n position?: PopoverSide\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n portal,\n position,\n closeOnClickOutside,\n closeOnEscape,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { PopoverAlign, PopoverSide } from \"@data-slot/popover\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n side?: PopoverSide\n align?: PopoverAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n portal?: boolean\n /** Compatibility alias. Prefer `side`. */\n position?: PopoverSide\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n portal,\n position,\n closeOnClickOutside,\n closeOnEscape,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
@@ -19,7 +19,7 @@
},
{
"path": "src/components/ui/popover/popover-content.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { PopoverAlign, PopoverSide } from \"@data-slot/popover\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: PopoverSide\n align?: PopoverAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n position?: PopoverSide\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n position,\n ...props\n} = Astro.props\n---\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { PopoverAlign, PopoverSide } from \"@data-slot/popover\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: PopoverSide\n align?: PopoverAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n /** Compatibility alias. Prefer `side`. */\n position?: PopoverSide\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n position,\n ...props\n} = Astro.props\n---\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/radio-group.json b/public/r/radio-group.json
index ef137f733..1f2625f85 100644
--- a/public/r/radio-group.json
+++ b/public/r/radio-group.json
@@ -4,12 +4,12 @@
"title": "Radio Group",
"description": "A set of checkable buttons, known as radio buttons, where no more than one of the buttons can be checked at a time.",
"dependencies": [
- "@data-slot/radio-group"
+ "@data-slot/radio-group@^1.0.1"
],
"files": [
{
"path": "src/components/ui/radio-group/radio-group.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultValue?: string\n name?: string\n disabled?: boolean\n readOnly?: boolean\n required?: boolean\n}\n\nconst {\n class: className,\n defaultValue,\n name,\n disabled,\n readOnly,\n required,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultValue?: string\n name?: string\n disabled?: boolean\n readOnly?: boolean\n required?: boolean\n}\n\nconst {\n class: className,\n defaultValue,\n name,\n disabled,\n readOnly,\n required,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/registry.json b/public/r/registry.json
index e01ccf999..15d80d9e6 100644
--- a/public/r/registry.json
+++ b/public/r/registry.json
@@ -13,7 +13,7 @@
],
"docs": "https://ui.full.dev/components/accordion/",
"dependencies": [
- "@data-slot/accordion",
+ "@data-slot/accordion@^1.0.1",
"@lucide/astro"
],
"files": [
@@ -77,7 +77,7 @@
],
"docs": "https://ui.full.dev/components/alert-dialog/",
"dependencies": [
- "@data-slot/alert-dialog"
+ "@data-slot/alert-dialog@^1.0.1"
],
"registryDependencies": [
"@fulldev/button"
@@ -201,10 +201,6 @@
"dependencies": [
"@lucide/astro"
],
- "registryDependencies": [
- "@fulldev/button",
- "@fulldev/dropdown-menu"
- ],
"files": [
{
"path": "src/components/ui/banner/banner.astro",
@@ -365,7 +361,7 @@
],
"docs": "https://ui.full.dev/components/collapsible/",
"dependencies": [
- "@data-slot/collapsible"
+ "@data-slot/collapsible@^1.0.1"
],
"files": [
{
@@ -396,7 +392,8 @@
],
"docs": "https://ui.full.dev/components/combobox/",
"dependencies": [
- "@data-slot/combobox",
+ "@data-slot/combobox@^1.0.1",
+ "@data-slot/core@^1.0.1",
"@lucide/astro"
],
"registryDependencies": [
@@ -463,8 +460,9 @@
],
"docs": "https://ui.full.dev/components/command/",
"dependencies": [
- "@data-slot/command",
- "@lucide/astro"
+ "@data-slot/command@^1.0.1",
+ "@lucide/astro",
+ "@data-slot/core@^1.0.1"
],
"registryDependencies": [
"@fulldev/dialog"
@@ -522,7 +520,7 @@
],
"docs": "https://ui.full.dev/components/dialog/",
"dependencies": [
- "@data-slot/dialog",
+ "@data-slot/dialog@^1.0.1",
"@lucide/astro"
],
"registryDependencies": [
@@ -585,7 +583,7 @@
],
"docs": "https://ui.full.dev/components/dropdown-menu/",
"dependencies": [
- "@data-slot/dropdown-menu",
+ "@data-slot/dropdown-menu@^1.0.1",
"@lucide/astro"
],
"files": [
@@ -800,8 +798,8 @@
],
"docs": "https://ui.full.dev/components/hover-card/",
"dependencies": [
- "@data-slot/hover-card",
- "@data-slot/core"
+ "@data-slot/hover-card@^1.0.1",
+ "@data-slot/core@^1.0.1"
],
"files": [
{
@@ -877,7 +875,6 @@
"docs": "https://ui.full.dev/components/input-group/",
"registryDependencies": [
"@fulldev/button",
- "@fulldev/dropdown-menu",
"@fulldev/input",
"@fulldev/textarea"
],
@@ -1131,7 +1128,7 @@
],
"docs": "https://ui.full.dev/components/navigation-menu/",
"dependencies": [
- "@data-slot/navigation-menu",
+ "@data-slot/navigation-menu@^1.0.1",
"@lucide/astro"
],
"files": [
@@ -1218,7 +1215,7 @@
],
"docs": "https://ui.full.dev/components/popover/",
"dependencies": [
- "@data-slot/popover"
+ "@data-slot/popover@^1.0.1"
],
"files": [
{
@@ -1293,7 +1290,7 @@
],
"docs": "https://ui.full.dev/components/radio-group/",
"dependencies": [
- "@data-slot/radio-group"
+ "@data-slot/radio-group@^1.0.1"
],
"files": [
{
@@ -1343,7 +1340,7 @@
],
"docs": "https://ui.full.dev/components/select/",
"dependencies": [
- "@data-slot/select",
+ "@data-slot/select@^1.0.1",
"@lucide/astro"
],
"files": [
@@ -1447,7 +1444,7 @@
],
"docs": "https://ui.full.dev/components/sheet/",
"dependencies": [
- "@data-slot/dialog",
+ "@data-slot/dialog@^1.0.1",
"@lucide/astro"
],
"registryDependencies": [
@@ -1503,7 +1500,7 @@
],
"docs": "https://ui.full.dev/components/sidebar/",
"dependencies": [
- "@data-slot/tooltip",
+ "@data-slot/tooltip@^1.0.1",
"@lucide/astro"
],
"registryDependencies": [
@@ -1624,7 +1621,7 @@
],
"docs": "https://ui.full.dev/components/slider/",
"dependencies": [
- "@data-slot/slider"
+ "@data-slot/slider@^1.0.1"
],
"files": [
{
@@ -1690,7 +1687,7 @@
],
"docs": "https://ui.full.dev/components/switch/",
"dependencies": [
- "@data-slot/switch"
+ "@data-slot/switch@^1.0.1"
],
"files": [
{
@@ -1761,7 +1758,7 @@
],
"docs": "https://ui.full.dev/components/tabs/",
"dependencies": [
- "@data-slot/tabs"
+ "@data-slot/tabs@^1.0.1"
],
"files": [
{
@@ -1836,7 +1833,7 @@
],
"docs": "https://ui.full.dev/components/toggle/",
"dependencies": [
- "@data-slot/toggle"
+ "@data-slot/toggle@^1.0.1"
],
"files": [
{
@@ -1883,7 +1880,7 @@
],
"docs": "https://ui.full.dev/components/tooltip/",
"dependencies": [
- "@data-slot/tooltip"
+ "@data-slot/tooltip@^1.0.1"
],
"files": [
{
@@ -2076,6 +2073,9 @@
"ui"
],
"docs": "https://ui.full.dev/components/layout/",
+ "dependencies": [
+ "@lexingtonthemes/seo@^0.2.0"
+ ],
"files": [
{
"path": "src/components/ui/layout/layout.astro",
diff --git a/public/r/select.json b/public/r/select.json
index 38e9cb3d5..10b5ca1c3 100644
--- a/public/r/select.json
+++ b/public/r/select.json
@@ -4,13 +4,13 @@
"title": "Select",
"description": "Displays a list of options for the user to pick from, triggered by a button.",
"dependencies": [
- "@data-slot/select",
+ "@data-slot/select@^1.0.1",
"@lucide/astro"
],
"files": [
{
"path": "src/components/ui/select/select.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Position, Side } from \"@data-slot/select\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultValue?: string\n defaultOpen?: boolean\n placeholder?: string\n disabled?: boolean\n required?: boolean\n name?: string\n position?: Position\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n highlightItemOnHover?: boolean\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultValue,\n defaultOpen,\n placeholder,\n disabled,\n required,\n name,\n position,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n highlightItemOnHover,\n lockScroll,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Position, Side } from \"@data-slot/select\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n mountStrategy?: \"lazy\" | \"eager\"\n defaultValue?: string\n defaultOpen?: boolean\n placeholder?: string\n disabled?: boolean\n required?: boolean\n name?: string\n position?: Position\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n highlightItemOnHover?: boolean\n lockScroll?: boolean\n}\n\nconst {\n mountStrategy,\n class: className,\n defaultValue,\n defaultOpen,\n placeholder,\n disabled,\n required,\n name,\n position,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n highlightItemOnHover,\n lockScroll,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
@@ -25,7 +25,7 @@
},
{
"path": "src/components/ui/select/select-content.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Position, Side } from \"@data-slot/select\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n position?: Position\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n position,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Position, Side } from \"@data-slot/select\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n position?: Position\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n position,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/sheet.json b/public/r/sheet.json
index ecf90e06e..9759879c3 100644
--- a/public/r/sheet.json
+++ b/public/r/sheet.json
@@ -4,7 +4,7 @@
"title": "Sheet",
"description": "A sliding panel component that appears from the edge of the screen.",
"dependencies": [
- "@data-slot/dialog",
+ "@data-slot/dialog@^1.0.1",
"@lucide/astro"
],
"registryDependencies": [
@@ -14,7 +14,7 @@
"files": [
{
"path": "src/components/ui/sheet/sheet.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n closeOnClickOutside,\n closeOnEscape,\n lockScroll,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n closeOnClickOutside,\n closeOnEscape,\n lockScroll,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/sidebar-1.json b/public/r/sidebar-1.json
index db9d030f2..daba5086c 100644
--- a/public/r/sidebar-1.json
+++ b/public/r/sidebar-1.json
@@ -23,7 +23,7 @@
"files": [
{
"path": "src/components/blocks/sidebar-1.astro",
- "content": "---\nimport ChevronDownIcon from \"@lucide/astro/icons/chevron-down\"\nimport SearchIcon from \"@lucide/astro/icons/search\"\n\nimport { cn } from \"@/lib/utils\"\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Command,\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandShortcut,\n} from \"@/components/ui/command\"\nimport { Dialog, DialogTrigger } from \"@/components/ui/dialog\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { Header, HeaderContainer, HeaderGroup } from \"@/components/ui/header\"\nimport { Icon } from \"@/components/ui/icon\"\nimport { Kbd } from \"@/components/ui/kbd\"\nimport { LogoImage, LogoText } from \"@/components/ui/logo\"\nimport { Separator } from \"@/components/ui/separator\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n SidebarTrigger,\n} from \"@/components/ui/sidebar\"\nimport { ThemeToggle } from \"@/components/ui/theme-toggle\"\n\ntype Props = {\n class?: string\n logo: {\n label: string\n href: string\n src?: any\n srcLight?: any\n srcDark?: any\n alt?: string\n }\n search: {\n label: string\n empty: string\n items: {\n label: string\n href: string\n title: string\n path: string\n description: string\n group: string\n }[]\n }\n breadcrumb: {\n items: {\n label: string\n href: string\n }[]\n menu: {\n label: string\n href: string\n }[]\n }\n navigation: {\n label: string\n href: string\n links?: {\n label: string\n href: string\n }[]\n }[]\n githubRepo: string\n}\n\nconst {\n class: className,\n logo,\n search,\n breadcrumb,\n navigation,\n githubRepo,\n}: Props = Astro.props\n\nconst normalizePath = (path: string) => {\n if (path === \"/\") return path\n\n return path.replace(/\\/$/, \"\")\n}\nconst currentPath = normalizePath(Astro.url.pathname)\nconst searchGroups = search.items.reduce<\n { label: string; items: typeof search.items }[]\n>((groups, item) => {\n const group = groups.find((entry) => entry.label === item.group)\n\n if (group) {\n group.items.push(item)\n } else {\n groups.push({ label: item.group, items: [item] })\n }\n\n return groups\n}, [])\n\nlet githubStars = \"Stars\"\n\ntry {\n const response = await fetch(`https://api.github.com/repos/${githubRepo}`)\n const data = await response.json()\n\n if (response.ok && typeof data.stargazers_count === \"number\") {\n githubStars = new Intl.NumberFormat().format(data.stargazers_count)\n }\n} catch {\n // Keep the fallback label when GitHub is unavailable.\n}\n---\n\n\n \n \n \n \n {logo.label} \n \n \n \n \n {search.label} \n \n ⌘ + K\n \n \n\n \n \n \n \n {search.empty} \n\n {\n searchGroups.map((group) => (\n \n {group.items.map((item) => (\n \n {item.label}\n {item.href} \n \n ))}\n \n ))\n }\n \n \n \n \n \n \n {\n navigation.map((group) => (\n \n {group.label} \n \n {(group.links ?? [group]).map((item) => (\n \n \n {item.label} \n \n \n ))}\n \n \n ))\n }\n \n \n \n \n \n \n \n \n \n \n {\n breadcrumb.items.map((item, index) => {\n const isLast = index === breadcrumb.items.length - 1\n const isHome = item.href === \"/\"\n const hasMenu =\n !isHome &&\n breadcrumb.menu.some(\n (menuItem) =>\n normalizePath(menuItem.href) ===\n normalizePath(item.href)\n )\n\n return (\n <>\n {index > 0 && (\n / \n )}\n \n {hasMenu ? (\n \n \n {item.label}\n \n \n \n \n {breadcrumb.menu.map((menuItem) => (\n \n {menuItem.label}\n \n ))}\n \n \n \n ) : isLast ? (\n {item.label} \n ) : (\n \n {item.label}\n \n )}\n \n >\n )\n })\n }\n {\n breadcrumb.menu.length > 0 && currentPath === \"/\" && (\n <>\n / \n \n \n \n \n \n \n \n {breadcrumb.menu.map((item) => (\n \n {item.label}\n \n ))}\n \n \n \n \n >\n )\n }\n \n \n \n \n \n \n {githubStars} \n \n \n \n \n \n \n \n \n\n\n",
+ "content": "---\nimport ChevronDownIcon from \"@lucide/astro/icons/chevron-down\"\nimport SearchIcon from \"@lucide/astro/icons/search\"\n\nimport { cn } from \"@/lib/utils\"\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Command,\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandShortcut,\n} from \"@/components/ui/command\"\nimport { DialogTrigger } from \"@/components/ui/dialog\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { Header, HeaderContainer, HeaderGroup } from \"@/components/ui/header\"\nimport { Icon } from \"@/components/ui/icon\"\nimport { Kbd } from \"@/components/ui/kbd\"\nimport { LogoImage, LogoText } from \"@/components/ui/logo\"\nimport { Separator } from \"@/components/ui/separator\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n SidebarTrigger,\n} from \"@/components/ui/sidebar\"\nimport { ThemeToggle } from \"@/components/ui/theme-toggle\"\n\ntype Props = {\n class?: string\n logo: {\n label: string\n href: string\n src?: any\n srcLight?: any\n srcDark?: any\n alt?: string\n }\n search: {\n label: string\n empty: string\n items: {\n label: string\n href: string\n title: string\n path: string\n description: string\n group: string\n }[]\n }\n breadcrumb: {\n items: {\n label: string\n href: string\n }[]\n menu: {\n label: string\n href: string\n }[]\n }\n navigation: {\n label: string\n href: string\n links?: {\n label: string\n href: string\n }[]\n }[]\n githubRepo: string\n}\n\nconst {\n class: className,\n logo,\n search,\n breadcrumb,\n navigation,\n githubRepo,\n}: Props = Astro.props\n\nconst normalizePath = (path: string) => {\n if (path === \"/\") return path\n\n return path.replace(/\\/$/, \"\")\n}\nconst currentPath = normalizePath(Astro.url.pathname)\nconst searchGroups = search.items.reduce<\n { label: string; items: typeof search.items }[]\n>((groups, item) => {\n const group = groups.find((entry) => entry.label === item.group)\n\n if (group) {\n group.items.push(item)\n } else {\n groups.push({ label: item.group, items: [item] })\n }\n\n return groups\n}, [])\n\nlet githubStars = \"Stars\"\n\ntry {\n const response = await fetch(`https://api.github.com/repos/${githubRepo}`)\n const data = await response.json()\n\n if (response.ok && typeof data.stargazers_count === \"number\") {\n githubStars = new Intl.NumberFormat().format(data.stargazers_count)\n }\n} catch {\n // Keep the fallback label when GitHub is unavailable.\n}\n---\n\n\n \n \n \n \n {logo.label} \n \n \n \n \n {search.label} \n \n ⌘ + K\n \n \n\n \n \n \n {search.empty} \n\n {\n searchGroups.map((group) => (\n \n {group.items.map((item) => (\n \n {item.label}\n {item.href} \n \n ))}\n \n ))\n }\n \n \n \n \n \n {\n navigation.map((group) => (\n \n {group.label} \n \n {(group.links ?? [group]).map((item) => (\n \n \n {item.label} \n \n \n ))}\n \n \n ))\n }\n \n \n \n \n \n \n \n \n \n \n {\n breadcrumb.items.map((item, index) => {\n const isLast = index === breadcrumb.items.length - 1\n const isHome = item.href === \"/\"\n const hasMenu =\n !isHome &&\n breadcrumb.menu.some(\n (menuItem) =>\n normalizePath(menuItem.href) ===\n normalizePath(item.href)\n )\n\n return (\n <>\n {index > 0 && (\n / \n )}\n \n {hasMenu ? (\n \n \n {item.label}\n \n \n \n \n {breadcrumb.menu.map((menuItem) => (\n \n {menuItem.label}\n \n ))}\n \n \n \n ) : isLast ? (\n {item.label} \n ) : (\n \n {item.label}\n \n )}\n \n >\n )\n })\n }\n {\n breadcrumb.menu.length > 0 && currentPath === \"/\" && (\n <>\n / \n \n \n \n \n \n \n \n {breadcrumb.menu.map((item) => (\n \n {item.label}\n \n ))}\n \n \n \n \n >\n )\n }\n \n \n \n \n \n \n {githubStars} \n \n \n \n \n \n \n \n \n\n\n",
"type": "registry:block"
}
],
diff --git a/public/r/sidebar.json b/public/r/sidebar.json
index e7827aefb..45669fa49 100644
--- a/public/r/sidebar.json
+++ b/public/r/sidebar.json
@@ -4,7 +4,7 @@
"title": "Sidebar",
"description": "A composable, themeable, and customizable Astro sidebar component.",
"dependencies": [
- "@data-slot/tooltip",
+ "@data-slot/tooltip@^1.0.1",
"@lucide/astro"
],
"registryDependencies": [
diff --git a/public/r/slider.json b/public/r/slider.json
index 3daffe9e0..a12da5a16 100644
--- a/public/r/slider.json
+++ b/public/r/slider.json
@@ -4,12 +4,12 @@
"title": "Slider",
"description": "An input where the user selects a value from within a given range.",
"dependencies": [
- "@data-slot/slider"
+ "@data-slot/slider@^1.0.1"
],
"files": [
{
"path": "src/components/ui/slider/slider.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype SliderValue = number | [number, number] | string\ntype ThumbAlignment = \"center\" | \"edge\" | \"edge-client-only\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultValue?: SliderValue\n min?: number\n max?: number\n step?: number\n largeStep?: number\n orientation?: \"horizontal\" | \"vertical\"\n thumbAlignment?: ThumbAlignment\n disabled?: boolean\n}\n\nconst {\n class: className,\n defaultValue,\n min,\n max,\n step,\n largeStep,\n orientation = \"horizontal\",\n thumbAlignment = \"edge\",\n disabled,\n ...props\n} = Astro.props\n\nconst serializedDefaultValue = Array.isArray(defaultValue)\n ? defaultValue.join(\",\")\n : defaultValue\nconst thumbCount = String(serializedDefaultValue ?? \"\").includes(\",\") ? 2 : 1\n---\n\n\n
\n
\n {\n Array.from({ length: thumbCount }).map(() => (\n
\n ))\n }\n
\n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype SliderValue = number | [number, number]\ntype ThumbAlignment = \"center\" | \"edge\" | \"edge-client-only\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultValue?: SliderValue\n min?: number\n max?: number\n step?: number\n largeStep?: number\n orientation?: \"horizontal\" | \"vertical\"\n thumbAlignment?: ThumbAlignment\n disabled?: boolean\n}\n\nconst {\n class: className,\n defaultValue,\n min,\n max,\n step,\n largeStep,\n orientation = \"horizontal\",\n thumbAlignment = \"center\",\n disabled,\n ...props\n} = Astro.props\n\nconst serializedDefaultValue = Array.isArray(defaultValue)\n ? defaultValue.join(\",\")\n : defaultValue\nconst thumbCount = String(serializedDefaultValue ?? \"\").includes(\",\") ? 2 : 1\n---\n\n\n
\n
\n {\n Array.from({ length: thumbCount }).map(() => (\n
\n ))\n }\n
\n
\n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/switch.json b/public/r/switch.json
index 91c66ac23..413b52ac5 100644
--- a/public/r/switch.json
+++ b/public/r/switch.json
@@ -4,12 +4,12 @@
"title": "Switch",
"description": "A control that allows the user to toggle between checked and not checked.",
"dependencies": [
- "@data-slot/switch"
+ "@data-slot/switch@^1.0.1"
],
"files": [
{
"path": "src/components/ui/switch/switch.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"span\"> & {\n defaultChecked?: boolean\n disabled?: boolean\n readOnly?: boolean\n required?: boolean\n name?: string\n size?: \"default\" | \"sm\"\n value?: string\n uncheckedValue?: string\n}\n\nconst {\n class: className,\n defaultChecked,\n disabled,\n readOnly,\n required,\n name,\n size = \"default\",\n value,\n uncheckedValue,\n ...props\n} = Astro.props\n\nconst initialChecked = defaultChecked === true\nconst switchStyle =\n \"peer group/switch focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 relative inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 aria-invalid:ring-3 data-disabled:cursor-not-allowed data-disabled:opacity-50 data-readonly:cursor-default\"\nconst switchSizeStyle = {\n sm: \"h-[14px] w-[24px]\",\n default: \"h-[18.4px] w-[32px]\",\n}\n---\n\n\n \n \n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"span\"> & {\n defaultChecked?: boolean\n disabled?: boolean\n readOnly?: boolean\n required?: boolean\n name?: string\n size?: \"default\" | \"sm\"\n value?: string\n uncheckedValue?: string\n}\n\nconst {\n class: className,\n defaultChecked,\n disabled,\n readOnly,\n required,\n name,\n size = \"default\",\n value,\n uncheckedValue,\n ...props\n} = Astro.props\n\nconst initialChecked = defaultChecked === true\nconst switchStyle =\n \"peer group/switch focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 relative inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 aria-invalid:ring-3 data-disabled:cursor-not-allowed data-disabled:opacity-50 data-readonly:cursor-default\"\nconst switchSizeStyle = {\n sm: \"h-[14px] w-[24px]\",\n default: \"h-[18.4px] w-[32px]\",\n}\n---\n\n\n \n \n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/tabs.json b/public/r/tabs.json
index 432876983..de8867333 100644
--- a/public/r/tabs.json
+++ b/public/r/tabs.json
@@ -4,17 +4,17 @@
"title": "Tabs",
"description": "A set of layered sections of content, known as tabs, that display one panel of content at a time.",
"dependencies": [
- "@data-slot/tabs"
+ "@data-slot/tabs@^1.0.1"
],
"files": [
{
"path": "src/components/ui/tabs/tabs.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultValue?: string\n orientation?: \"horizontal\" | \"vertical\"\n activationMode?: \"auto\" | \"manual\"\n}\n\nconst {\n class: className,\n defaultValue,\n orientation = \"horizontal\",\n activationMode,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultValue?: string\n orientation?: \"horizontal\" | \"vertical\"\n activationMode?: \"auto\" | \"manual\"\n}\n\nconst {\n class: className,\n defaultValue,\n orientation = \"horizontal\",\n activationMode,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
"path": "src/components/ui/tabs/tabs-content.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n value?: string\n}\n\nconst { class: className, hidden = true, value, ...props } = Astro.props\n---\n\n\n \n
\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n value: string\n}\n\nconst { class: className, hidden = true, value, ...props } = Astro.props\n---\n\n\n \n
\n",
"type": "registry:ui"
},
{
@@ -29,7 +29,7 @@
},
{
"path": "src/components/ui/tabs/tabs-trigger.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"button\"> & {\n value?: string\n}\n\nconst { class: className, value, ...props } = Astro.props\n---\n\n\n \n \n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"button\"> & {\n value: string\n}\n\nconst { class: className, value, type = \"button\", ...props } = Astro.props\n---\n\n\n \n \n",
"type": "registry:ui"
},
{
diff --git a/public/r/toggle.json b/public/r/toggle.json
index 2d1b9ad59..f634f3eb7 100644
--- a/public/r/toggle.json
+++ b/public/r/toggle.json
@@ -4,12 +4,12 @@
"title": "Toggle",
"description": "A two-state button that can be either on or off.",
"dependencies": [
- "@data-slot/toggle"
+ "@data-slot/toggle@^1.0.1"
],
"files": [
{
"path": "src/components/ui/toggle/toggle.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\nimport { toggleVariants, type ToggleVariantProps } from \"./toggle-variants\"\n\ntype Props = HTMLAttributes<\"button\"> &\n ToggleVariantProps & {\n defaultPressed?: boolean\n disabled?: boolean\n }\n\nconst {\n class: className,\n variant = \"default\",\n size = \"default\",\n defaultPressed,\n disabled,\n type = \"button\",\n ...props\n} = Astro.props\n---\n\n\n \n \n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\nimport { toggleVariants, type ToggleVariantProps } from \"./toggle-variants\"\n\ntype Props = HTMLAttributes<\"button\"> &\n ToggleVariantProps & {\n defaultPressed?: boolean\n disabled?: boolean\n }\n\nconst {\n class: className,\n variant = \"default\",\n size = \"default\",\n defaultPressed,\n disabled,\n type = \"button\",\n ...props\n} = Astro.props\n---\n\n\n \n \n\n\n",
"type": "registry:ui"
},
{
diff --git a/public/r/tooltip.json b/public/r/tooltip.json
index 2d881c258..ce5107bee 100644
--- a/public/r/tooltip.json
+++ b/public/r/tooltip.json
@@ -4,12 +4,12 @@
"title": "Tooltip",
"description": "Displays contextual information when a user hovers or focuses a trigger.",
"dependencies": [
- "@data-slot/tooltip"
+ "@data-slot/tooltip@^1.0.1"
],
"files": [
{
"path": "src/components/ui/tooltip/tooltip.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { TooltipAlign, TooltipSide } from \"@data-slot/tooltip\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n delay?: number\n skipDelayDuration?: number\n side?: TooltipSide\n align?: TooltipAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n portal?: boolean\n}\n\nconst {\n class: className,\n delay = 300,\n skipDelayDuration = 300,\n side = \"top\",\n align = \"center\",\n sideOffset = 4,\n alignOffset = 0,\n avoidCollisions = true,\n collisionPadding = 8,\n portal = true,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { TooltipAlign, TooltipSide } from \"@data-slot/tooltip\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n mountStrategy?: \"lazy\" | \"eager\"\n delay?: number\n skipDelayDuration?: number\n side?: TooltipSide\n align?: TooltipAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n portal?: boolean\n}\n\nconst {\n mountStrategy,\n class: className,\n delay = 300,\n skipDelayDuration = 300,\n side = \"top\",\n align = \"center\",\n sideOffset = 4,\n alignOffset = 0,\n avoidCollisions = true,\n collisionPadding = 8,\n portal = true,\n ...props\n} = Astro.props\n---\n\n\n \n
\n\n\n",
"type": "registry:ui"
},
{
@@ -19,7 +19,7 @@
},
{
"path": "src/components/ui/tooltip/tooltip-content.astro",
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { TooltipAlign, TooltipSide } from \"@data-slot/tooltip\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: TooltipSide\n align?: TooltipAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n",
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { TooltipAlign, TooltipSide } from \"@data-slot/tooltip\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: TooltipSide\n align?: TooltipAlign\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n\n",
"type": "registry:ui"
},
{
diff --git a/registry.json b/registry.json
index 2eaed2dec..269e38119 100644
--- a/registry.json
+++ b/registry.json
@@ -10,7 +10,7 @@
"description": "A vertically stacked set of interactive headings that each reveal a section of content.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/accordion/",
- "dependencies": ["@data-slot/accordion", "@lucide/astro"],
+ "dependencies": ["@data-slot/accordion@^1.0.1", "@lucide/astro"],
"files": [
{
"path": "src/components/ui/accordion/accordion.astro",
@@ -67,7 +67,7 @@
"description": "A modal dialog for important confirmations that expects a response.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/alert-dialog/",
- "dependencies": ["@data-slot/alert-dialog"],
+ "dependencies": ["@data-slot/alert-dialog@^1.0.1"],
"registryDependencies": ["@fulldev/button"],
"files": [
{
@@ -180,7 +180,6 @@
"categories": ["ui"],
"docs": "https://ui.full.dev/components/banner/",
"dependencies": ["@lucide/astro"],
- "registryDependencies": ["@fulldev/button", "@fulldev/dropdown-menu"],
"files": [
{
"path": "src/components/ui/banner/banner.astro",
@@ -328,7 +327,7 @@
"description": "An interactive component which expands/collapses a panel.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/collapsible/",
- "dependencies": ["@data-slot/collapsible"],
+ "dependencies": ["@data-slot/collapsible@^1.0.1"],
"files": [
{
"path": "src/components/ui/collapsible/collapsible.astro",
@@ -355,7 +354,11 @@
"description": "Autocomplete input with a list of suggestions.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/combobox/",
- "dependencies": ["@data-slot/combobox", "@lucide/astro"],
+ "dependencies": [
+ "@data-slot/combobox@^1.0.1",
+ "@data-slot/core@^1.0.1",
+ "@lucide/astro"
+ ],
"registryDependencies": ["@fulldev/input-group"],
"files": [
{
@@ -415,7 +418,11 @@
"description": "Command menu for search and quick actions.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/command/",
- "dependencies": ["@data-slot/command", "@lucide/astro"],
+ "dependencies": [
+ "@data-slot/command@^1.0.1",
+ "@lucide/astro",
+ "@data-slot/core@^1.0.1"
+ ],
"registryDependencies": ["@fulldev/dialog"],
"files": [
{
@@ -467,7 +474,7 @@
"description": "A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/dialog/",
- "dependencies": ["@data-slot/dialog", "@lucide/astro"],
+ "dependencies": ["@data-slot/dialog@^1.0.1", "@lucide/astro"],
"registryDependencies": ["@fulldev/button"],
"files": [
{
@@ -523,7 +530,7 @@
"description": "Displays a menu to the user, such as a set of actions or functions, triggered by a button.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/dropdown-menu/",
- "dependencies": ["@data-slot/dropdown-menu", "@lucide/astro"],
+ "dependencies": ["@data-slot/dropdown-menu@^1.0.1", "@lucide/astro"],
"files": [
{
"path": "src/components/ui/dropdown-menu/dropdown-menu.astro",
@@ -717,7 +724,10 @@
"description": "For sighted users to preview content available behind a link.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/hover-card/",
- "dependencies": ["@data-slot/hover-card", "@data-slot/core"],
+ "dependencies": [
+ "@data-slot/hover-card@^1.0.1",
+ "@data-slot/core@^1.0.1"
+ ],
"files": [
{
"path": "src/components/ui/hover-card/hover-card.astro",
@@ -783,7 +793,6 @@
"docs": "https://ui.full.dev/components/input-group/",
"registryDependencies": [
"@fulldev/button",
- "@fulldev/dropdown-menu",
"@fulldev/input",
"@fulldev/textarea"
],
@@ -1011,7 +1020,7 @@
"description": "A collection of links for navigating websites.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/navigation-menu/",
- "dependencies": ["@data-slot/navigation-menu", "@lucide/astro"],
+ "dependencies": ["@data-slot/navigation-menu@^1.0.1", "@lucide/astro"],
"files": [
{
"path": "src/components/ui/navigation-menu/navigation-menu.astro",
@@ -1089,7 +1098,7 @@
"description": "Displays rich content in a floating layer, triggered by a button.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/popover/",
- "dependencies": ["@data-slot/popover"],
+ "dependencies": ["@data-slot/popover@^1.0.1"],
"files": [
{
"path": "src/components/ui/popover/popover.astro",
@@ -1158,7 +1167,7 @@
"description": "A set of checkable buttons, known as radio buttons, where no more than one of the buttons can be checked at a time.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/radio-group/",
- "dependencies": ["@data-slot/radio-group"],
+ "dependencies": ["@data-slot/radio-group@^1.0.1"],
"files": [
{
"path": "src/components/ui/radio-group/radio-group.astro",
@@ -1200,7 +1209,7 @@
"description": "Displays a list of options for the user to pick from, triggered by a button.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/select/",
- "dependencies": ["@data-slot/select", "@lucide/astro"],
+ "dependencies": ["@data-slot/select@^1.0.1", "@lucide/astro"],
"files": [
{
"path": "src/components/ui/select/select.astro",
@@ -1295,7 +1304,7 @@
"description": "A sliding panel component that appears from the edge of the screen.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/sheet/",
- "dependencies": ["@data-slot/dialog", "@lucide/astro"],
+ "dependencies": ["@data-slot/dialog@^1.0.1", "@lucide/astro"],
"registryDependencies": ["@fulldev/button", "@fulldev/dialog"],
"files": [
{
@@ -1343,7 +1352,7 @@
"description": "A composable, themeable, and customizable Astro sidebar component.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/sidebar/",
- "dependencies": ["@data-slot/tooltip", "@lucide/astro"],
+ "dependencies": ["@data-slot/tooltip@^1.0.1", "@lucide/astro"],
"registryDependencies": [
"@fulldev/layout",
"@fulldev/button",
@@ -1459,7 +1468,7 @@
"description": "An input where the user selects a value from within a given range.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/slider/",
- "dependencies": ["@data-slot/slider"],
+ "dependencies": ["@data-slot/slider@^1.0.1"],
"files": [
{
"path": "src/components/ui/slider/slider.astro",
@@ -1515,7 +1524,7 @@
"description": "A control that allows the user to toggle between checked and not checked.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/switch/",
- "dependencies": ["@data-slot/switch"],
+ "dependencies": ["@data-slot/switch@^1.0.1"],
"files": [
{
"path": "src/components/ui/switch/switch.astro",
@@ -1580,7 +1589,7 @@
"description": "A set of layered sections of content, known as tabs, that display one panel of content at a time.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/tabs/",
- "dependencies": ["@data-slot/tabs"],
+ "dependencies": ["@data-slot/tabs@^1.0.1"],
"files": [
{
"path": "src/components/ui/tabs/tabs.astro",
@@ -1649,7 +1658,7 @@
"description": "A two-state button that can be either on or off.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/toggle/",
- "dependencies": ["@data-slot/toggle"],
+ "dependencies": ["@data-slot/toggle@^1.0.1"],
"files": [
{
"path": "src/components/ui/toggle/toggle.astro",
@@ -1690,7 +1699,7 @@
"description": "Displays contextual information when a user hovers or focuses a trigger.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/tooltip/",
- "dependencies": ["@data-slot/tooltip"],
+ "dependencies": ["@data-slot/tooltip@^1.0.1"],
"files": [
{
"path": "src/components/ui/tooltip/tooltip.astro",
@@ -1876,6 +1885,7 @@
"description": "Page-shell primitives for the root html, head, body, and main structure.",
"categories": ["ui"],
"docs": "https://ui.full.dev/components/layout/",
+ "dependencies": ["@lexingtonthemes/seo@^0.2.0"],
"files": [
{
"path": "src/components/ui/layout/layout.astro",
diff --git a/src/components/blocks/blocks-1.astro b/src/components/blocks/blocks-1.astro
index 6e73e030f..c06e66e20 100644
--- a/src/components/blocks/blocks-1.astro
+++ b/src/components/blocks/blocks-1.astro
@@ -15,6 +15,7 @@ import { buttonVariants } from "@/components/ui/button/button-variants"
import {
DropdownMenu,
DropdownMenuContent,
+ DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { SectionContainer } from "@/components/ui/section"
@@ -129,6 +130,7 @@ const openLinks = markdownUrl
variant="outline"
size="xs"
data-source={copyButton?.source}
+ data-blocks-copy
aria-label={labels.copyMarkdown}
>
@@ -148,11 +150,10 @@ const openLinks = markdownUrl
{openLinks.map((link) => (
-
{link.icon === "markdown" && }
{link.icon === "chatgpt" && (
@@ -170,7 +171,7 @@ const openLinks = markdownUrl
{link.icon === "cursor" && }
{link.label}
-
+
))}
@@ -224,27 +225,26 @@ const openLinks = markdownUrl
-
diff --git a/src/components/blocks/doc-1.astro b/src/components/blocks/doc-1.astro
index 7189a58fb..23967a4a8 100644
--- a/src/components/blocks/doc-1.astro
+++ b/src/components/blocks/doc-1.astro
@@ -21,6 +21,7 @@ import {
import {
DropdownMenu,
DropdownMenuContent,
+ DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { SectionContainer } from "@/components/ui/section"
@@ -180,11 +181,10 @@ const openLinks = markdownUrl
{openLinks.map((link) => (
-
{link.icon === "markdown" && }
{link.icon === "chatgpt" && (
@@ -202,7 +202,7 @@ const openLinks = markdownUrl
{link.icon === "cursor" && }
{link.label}
-
+
))}
@@ -299,38 +299,52 @@ const openLinks = markdownUrl
}
-
diff --git a/src/components/blocks/sidebar-1.astro b/src/components/blocks/sidebar-1.astro
index 25cfebdab..65f5050c8 100644
--- a/src/components/blocks/sidebar-1.astro
+++ b/src/components/blocks/sidebar-1.astro
@@ -23,11 +23,12 @@ import {
CommandList,
CommandShortcut,
} from "@/components/ui/command"
-import { Dialog, DialogTrigger } from "@/components/ui/dialog"
+import { DialogTrigger } from "@/components/ui/dialog"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
+ DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Header, HeaderContainer, HeaderGroup } from "@/components/ui/header"
@@ -139,7 +140,7 @@ try {
-
+
{logo.label}
-
+
-
-
-
-
- {search.empty}
+
+
+
+ {search.empty}
- {
- searchGroups.map((group) => (
-
- {group.items.map((item) => (
-
- {item.label}
- {item.href}
-
- ))}
-
- ))
- }
-
-
-
-
+ {
+ searchGroups.map((group) => (
+
+ {group.items.map((item) => (
+
+ {item.label}
+ {item.href}
+
+ ))}
+
+ ))
+ }
+
+
+
{breadcrumb.menu.map((menuItem) => (
-
{menuItem.label}
-
+
))}
@@ -308,12 +313,9 @@ try {
{breadcrumb.menu.map((item) => (
-
+
{item.label}
-
+
))}
diff --git a/src/components/live-code.astro b/src/components/live-code.astro
index b55b35192..1a6f98a6b 100644
--- a/src/components/live-code.astro
+++ b/src/components/live-code.astro
@@ -117,27 +117,29 @@ const installButtonId = installCommand
-
diff --git a/src/components/ui/accordion/accordion.astro b/src/components/ui/accordion/accordion.astro
index 7a82a905c..dca540513 100644
--- a/src/components/ui/accordion/accordion.astro
+++ b/src/components/ui/accordion/accordion.astro
@@ -48,6 +48,12 @@ const serializedDefaultValue = Array.isArray(defaultValue)
diff --git a/src/components/ui/alert-dialog/alert-dialog.astro b/src/components/ui/alert-dialog/alert-dialog.astro
index 24a1c7163..75369038e 100644
--- a/src/components/ui/alert-dialog/alert-dialog.astro
+++ b/src/components/ui/alert-dialog/alert-dialog.astro
@@ -33,6 +33,12 @@ const {
diff --git a/src/components/ui/button/button.astro b/src/components/ui/button/button.astro
index c93606402..bcd563747 100644
--- a/src/components/ui/button/button.astro
+++ b/src/components/ui/button/button.astro
@@ -15,12 +15,15 @@ const {
size,
...props
} = Astro.props
+
+const attributes: Record = { ...props }
+if (Tag === "button") attributes.type ??= "button"
---
diff --git a/src/components/ui/collapsible/collapsible.astro b/src/components/ui/collapsible/collapsible.astro
index bb715aab8..5d4663c66 100644
--- a/src/components/ui/collapsible/collapsible.astro
+++ b/src/components/ui/collapsible/collapsible.astro
@@ -29,6 +29,12 @@ const {
diff --git a/src/components/ui/combobox/combobox-content.astro b/src/components/ui/combobox/combobox-content.astro
index 534469154..c9a0e8e9c 100644
--- a/src/components/ui/combobox/combobox-content.astro
+++ b/src/components/ui/combobox/combobox-content.astro
@@ -38,7 +38,7 @@ const {
data-align-offset={alignOffset}
data-avoid-collisions={avoidCollisions}
data-collision-padding={collisionPadding}
- class="isolate z-50"
+ class="isolate z-[1000]"
>
diff --git a/src/components/ui/command/command-dialog.astro b/src/components/ui/command/command-dialog.astro
index 8c23088b4..f322137ce 100644
--- a/src/components/ui/command/command-dialog.astro
+++ b/src/components/ui/command/command-dialog.astro
@@ -25,6 +25,7 @@ const {
---
+
import { create } from "@data-slot/command"
+ import { getParts } from "@data-slot/core"
- const initCommand = () => {
- create()
+ const controllers: ReturnType = []
+ const initialize = () => controllers.push(...create())
+ initialize()
+ document.addEventListener("astro:page-load", initialize)
+ document.addEventListener("astro:before-swap", () => {
+ for (const controller of controllers) controller.destroy()
+ controllers.length = 0
+ })
- document.querySelectorAll("[data-slot=command]").forEach((command) => {
- if (!(command instanceof HTMLElement)) return
- if (command.dataset.linkNavigation === "true") return
-
- command.dataset.linkNavigation = "true"
- command.addEventListener("command:select", (event) => {
- const { detail } = event as CustomEvent<{ value?: unknown }>
- const value = detail?.value
- if (typeof value !== "string") return
-
- const item = Array.from(
- command.querySelectorAll("[data-slot=command-item][href]")
- ).find((item) => item.getAttribute("data-value") === value)
- const href = item?.getAttribute("href")
-
- if (href) window.location.href = href
- })
- })
- }
-
- initCommand()
-
- document.addEventListener("astro:page-load", initCommand)
+ // Data Slot selection does not activate links. Preserve native navigation.
+ document.addEventListener(
+ "keydown",
+ (event) => {
+ if (
+ event.key !== "Enter" ||
+ event.defaultPrevented ||
+ event.isComposing ||
+ event.keyCode === 229
+ )
+ return
+ const input = event.target
+ if (
+ !(input instanceof HTMLInputElement) ||
+ input.dataset.slot !== "command-input"
+ )
+ return
+ const root = input.closest('[data-slot="command"]')
+ if (!root) return
+ const item = getParts(root, "command-item").find(
+ (item) =>
+ item.hasAttribute("data-selected") &&
+ item.hasAttribute("href") &&
+ item.getAttribute("aria-disabled") !== "true"
+ )
+ if (!item) return
+ event.preventDefault()
+ item.click()
+ },
+ true
+ )
diff --git a/src/components/ui/dialog/dialog.astro b/src/components/ui/dialog/dialog.astro
index 00537d5f4..12de31441 100644
--- a/src/components/ui/dialog/dialog.astro
+++ b/src/components/ui/dialog/dialog.astro
@@ -36,6 +36,12 @@ const {
diff --git a/src/components/ui/dropdown-menu/dropdown-menu-content.astro b/src/components/ui/dropdown-menu/dropdown-menu-content.astro
index f1c58d6fa..2bb292d2d 100644
--- a/src/components/ui/dropdown-menu/dropdown-menu-content.astro
+++ b/src/components/ui/dropdown-menu/dropdown-menu-content.astro
@@ -35,7 +35,7 @@ const {
data-align-offset={alignOffset}
data-avoid-collisions={avoidCollisions}
data-collision-padding={collisionPadding}
- class="isolate z-50 outline-none"
+ class="isolate z-[1000] outline-none"
>
& {
- disabled?: boolean
- variant?: "default" | "destructive"
- inset?: boolean
-}
+type Props = HTMLAttributes<"button"> &
+ HTMLAttributes<"a"> & {
+ as?: "button" | "a"
+ disabled?: boolean
+ variant?: "default" | "destructive"
+ inset?: boolean
+ }
const {
+ as: Tag = "href" in Astro.props ? "a" : "button",
class: className,
type = "button",
disabled,
@@ -19,13 +22,13 @@ const {
} = Astro.props
---
-
-
+
+
+
diff --git a/src/components/ui/dropdown-menu/dropdown-menu.astro b/src/components/ui/dropdown-menu/dropdown-menu.astro
index d802e624a..79bb4ef03 100644
--- a/src/components/ui/dropdown-menu/dropdown-menu.astro
+++ b/src/components/ui/dropdown-menu/dropdown-menu.astro
@@ -67,6 +67,12 @@ const defaultValuesAttr =
diff --git a/src/components/ui/hover-card/hover-card-content.astro b/src/components/ui/hover-card/hover-card-content.astro
index 81d15520f..cdae7ef2a 100644
--- a/src/components/ui/hover-card/hover-card-content.astro
+++ b/src/components/ui/hover-card/hover-card-content.astro
@@ -34,7 +34,7 @@ const {
data-align-offset={alignOffset}
data-avoid-collisions={avoidCollisions}
data-collision-padding={collisionPadding}
- class="isolate z-50"
+ class="isolate z-[1000]"
>
& {
+ mountStrategy?: "lazy" | "eager"
defaultOpen?: boolean
open?: boolean
delay?: number
@@ -21,6 +22,7 @@ type Props = HTMLAttributes<"div"> & {
}
const {
+ mountStrategy,
class: className,
defaultOpen,
open,
@@ -42,6 +44,7 @@ const {
diff --git a/src/components/ui/navigation-menu/navigation-menu-positioner.astro b/src/components/ui/navigation-menu/navigation-menu-positioner.astro
index 083695271..be8199df4 100644
--- a/src/components/ui/navigation-menu/navigation-menu-positioner.astro
+++ b/src/components/ui/navigation-menu/navigation-menu-positioner.astro
@@ -29,7 +29,7 @@ const {
data-align={align}
data-align-offset={alignOffset}
class={cn(
- "isolate z-50 h-(--positioner-height) w-(--positioner-width) max-w-(--available-width) transition-[top,left,right,bottom] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-instant:transition-none data-[side=bottom]:before:top-[-10px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0",
+ "isolate z-[1000] h-(--positioner-height) w-(--positioner-width) max-w-(--available-width) transition-[top,left,right,bottom] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-instant:transition-none data-[side=bottom]:before:top-[-10px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0",
className
)}
>
diff --git a/src/components/ui/navigation-menu/navigation-menu.astro b/src/components/ui/navigation-menu/navigation-menu.astro
index df90944ce..f14bb8b17 100644
--- a/src/components/ui/navigation-menu/navigation-menu.astro
+++ b/src/components/ui/navigation-menu/navigation-menu.astro
@@ -6,6 +6,7 @@ import { cn } from "@/lib/utils"
import NavigationMenuPositioner from "./navigation-menu-positioner.astro"
type Props = HTMLAttributes<"nav"> & {
+ mountStrategy?: "lazy" | "eager"
delayOpen?: number
delayClose?: number
openOnFocus?: boolean
@@ -19,6 +20,7 @@ type Props = HTMLAttributes<"nav"> & {
}
const {
+ mountStrategy,
class: className = "",
delayOpen = 0,
delayClose = 0,
@@ -37,6 +39,7 @@ const {
import { create } from "@data-slot/navigation-menu"
- create()
- document.addEventListener("astro:page-load", () => create())
+ const controllers: ReturnType = []
+ const initialize = () => controllers.push(...create())
+ initialize()
+ document.addEventListener("astro:page-load", initialize)
+ document.addEventListener("astro:before-swap", () => {
+ for (const controller of controllers) controller.destroy()
+ controllers.length = 0
+ })
diff --git a/src/components/ui/popover/popover-content.astro b/src/components/ui/popover/popover-content.astro
index 24695a73c..4c33daa56 100644
--- a/src/components/ui/popover/popover-content.astro
+++ b/src/components/ui/popover/popover-content.astro
@@ -11,6 +11,7 @@ type Props = HTMLAttributes<"div"> & {
alignOffset?: number
avoidCollisions?: boolean
collisionPadding?: number
+ /** Compatibility alias. Prefer `side`. */
position?: PopoverSide
}
@@ -38,7 +39,7 @@ const {
data-avoid-collisions={avoidCollisions}
data-collision-padding={collisionPadding}
data-position={position}
- class="isolate z-50"
+ class="isolate z-[1000]"
>
& {
avoidCollisions?: boolean
collisionPadding?: number
portal?: boolean
+ /** Compatibility alias. Prefer `side`. */
position?: PopoverSide
closeOnClickOutside?: boolean
closeOnEscape?: boolean
@@ -55,6 +56,12 @@ const {
diff --git a/src/components/ui/radio-group/radio-group.astro b/src/components/ui/radio-group/radio-group.astro
index a9d8646b0..6d39ad9f2 100644
--- a/src/components/ui/radio-group/radio-group.astro
+++ b/src/components/ui/radio-group/radio-group.astro
@@ -38,6 +38,12 @@ const {
diff --git a/src/components/ui/select/select-content.astro b/src/components/ui/select/select-content.astro
index a0279814d..c30aa09f2 100644
--- a/src/components/ui/select/select-content.astro
+++ b/src/components/ui/select/select-content.astro
@@ -38,7 +38,7 @@ const {
data-align-offset={alignOffset}
data-avoid-collisions={avoidCollisions}
data-collision-padding={collisionPadding}
- class="isolate z-50"
+ class="isolate z-[1000]"
>
& {
+ mountStrategy?: "lazy" | "eager"
defaultValue?: string
defaultOpen?: boolean
placeholder?: string
@@ -23,6 +24,7 @@ type Props = HTMLAttributes<"div"> & {
}
const {
+ mountStrategy,
class: className,
defaultValue,
defaultOpen,
@@ -45,6 +47,7 @@ const {
import { create } from "@data-slot/select"
- const initSelect = () => {
- create()
- }
-
- initSelect()
-
- document.addEventListener("astro:page-load", initSelect)
+ const controllers: ReturnType
= []
+ const initialize = () => controllers.push(...create())
+ initialize()
+ document.addEventListener("astro:page-load", initialize)
+ document.addEventListener("astro:before-swap", () => {
+ for (const controller of controllers) controller.destroy()
+ controllers.length = 0
+ })
diff --git a/src/components/ui/sheet/sheet.astro b/src/components/ui/sheet/sheet.astro
index 28643107b..84b8d63ab 100644
--- a/src/components/ui/sheet/sheet.astro
+++ b/src/components/ui/sheet/sheet.astro
@@ -33,6 +33,12 @@ const {
diff --git a/src/components/ui/slider/slider.astro b/src/components/ui/slider/slider.astro
index cfcfb6adf..0d0778ada 100644
--- a/src/components/ui/slider/slider.astro
+++ b/src/components/ui/slider/slider.astro
@@ -3,7 +3,7 @@ import type { HTMLAttributes } from "astro/types"
import { cn } from "@/lib/utils"
-type SliderValue = number | [number, number] | string
+type SliderValue = number | [number, number]
type ThumbAlignment = "center" | "edge" | "edge-client-only"
type Props = HTMLAttributes<"div"> & {
@@ -25,7 +25,7 @@ const {
step,
largeStep,
orientation = "horizontal",
- thumbAlignment = "edge",
+ thumbAlignment = "center",
disabled,
...props
} = Astro.props
@@ -82,6 +82,12 @@ const thumbCount = String(serializedDefaultValue ?? "").includes(",") ? 2 : 1
diff --git a/src/components/ui/switch/switch.astro b/src/components/ui/switch/switch.astro
index 3b9c01499..7f2a60806 100644
--- a/src/components/ui/switch/switch.astro
+++ b/src/components/ui/switch/switch.astro
@@ -69,6 +69,12 @@ const switchSizeStyle = {
diff --git a/src/components/ui/tabs/tabs-content.astro b/src/components/ui/tabs/tabs-content.astro
index 41b2f3699..c6b0dbce7 100644
--- a/src/components/ui/tabs/tabs-content.astro
+++ b/src/components/ui/tabs/tabs-content.astro
@@ -4,7 +4,7 @@ import type { HTMLAttributes } from "astro/types"
import { cn } from "@/lib/utils"
type Props = HTMLAttributes<"div"> & {
- value?: string
+ value: string
}
const { class: className, hidden = true, value, ...props } = Astro.props
diff --git a/src/components/ui/tabs/tabs-trigger.astro b/src/components/ui/tabs/tabs-trigger.astro
index 4d98187d8..db7505900 100644
--- a/src/components/ui/tabs/tabs-trigger.astro
+++ b/src/components/ui/tabs/tabs-trigger.astro
@@ -4,14 +4,15 @@ import type { HTMLAttributes } from "astro/types"
import { cn } from "@/lib/utils"
type Props = HTMLAttributes<"button"> & {
- value?: string
+ value: string
}
-const { class: className, value, ...props } = Astro.props
+const { class: className, value, type = "button", ...props } = Astro.props
---
import { create } from "@data-slot/tabs"
- create()
- document.addEventListener("astro:page-load", () => create())
+ const controllers: ReturnType = []
+ const initialize = () => controllers.push(...create())
+ initialize()
+ document.addEventListener("astro:page-load", initialize)
+ document.addEventListener("astro:before-swap", () => {
+ for (const controller of controllers) controller.destroy()
+ controllers.length = 0
+ })
diff --git a/src/components/ui/toggle/toggle.astro b/src/components/ui/toggle/toggle.astro
index 2f5a420d3..e5e92d443 100644
--- a/src/components/ui/toggle/toggle.astro
+++ b/src/components/ui/toggle/toggle.astro
@@ -38,6 +38,12 @@ const {
diff --git a/src/components/ui/tooltip/tooltip-content.astro b/src/components/ui/tooltip/tooltip-content.astro
index b17b438b1..a7100ac09 100644
--- a/src/components/ui/tooltip/tooltip-content.astro
+++ b/src/components/ui/tooltip/tooltip-content.astro
@@ -35,7 +35,7 @@ const {
data-align-offset={alignOffset}
data-avoid-collisions={avoidCollisions}
data-collision-padding={collisionPadding}
- class="isolate z-50"
+ class="isolate z-[1000]"
>
& {
+ mountStrategy?: "lazy" | "eager"
delay?: number
skipDelayDuration?: number
side?: TooltipSide
@@ -17,6 +18,7 @@ type Props = HTMLAttributes<"div"> & {
}
const {
+ mountStrategy,
class: className,
delay = 300,
skipDelayDuration = 300,
@@ -33,6 +35,7 @@ const {
import { create } from "@data-slot/tooltip"
- create()
- document.addEventListener("astro:page-load", () => create())
+ const controllers: ReturnType
= []
+ const initialize = () => controllers.push(...create())
+ initialize()
+ document.addEventListener("astro:page-load", initialize)
+ document.addEventListener("astro:before-swap", () => {
+ for (const controller of controllers) controller.destroy()
+ controllers.length = 0
+ })
diff --git a/src/content/pages/components/alert-dialog.mdx b/src/content/pages/components/alert-dialog.mdx
index 07fb81c12..a68071ca5 100644
--- a/src/content/pages/components/alert-dialog.mdx
+++ b/src/content/pages/components/alert-dialog.mdx
@@ -101,11 +101,41 @@ AlertDialog
confirmations.
- Keep `AlertDialogTitle` and `AlertDialogDescription` inside
`AlertDialogContent` so screen readers announce the dialog context clearly.
-- Pair the destructive path with `AlertDialogAction` and the safe path with
- `AlertDialogCancel`.
+- Use `AlertDialogCancel` for dismissive actions. It closes the dialog
+ automatically.
+- `AlertDialogAction` is an action hook and does not close the dialog. Run the
+ confirmation first, then close the dialog with the documented
+ `alert-dialog:set` event when the action succeeds.
- Use `size="sm"` on `AlertDialogContent` for compact confirmations and
`AlertDialogMedia` when the dialog needs an icon or visual cue.
+```astro
+
+ Delete account
+
+ Delete this account?
+ This cannot be undone.
+
+ Delete account
+
+
+
+
+
+```
+
## API Reference
See the [GitHub source code](https://github.com/fulldotdev/ui/tree/main/src/components/ui/alert-dialog) for more information on props.
diff --git a/src/content/pages/components/command.mdx b/src/content/pages/components/command.mdx
index ea883db52..0bcd9061e 100644
--- a/src/content/pages/components/command.mdx
+++ b/src/content/pages/components/command.mdx
@@ -130,6 +130,39 @@ Command
└── CommandItem
```
+### Command dialog
+
+`CommandDialog` includes its own Dialog root. Put `DialogTrigger` in its `trigger`
+slot; wrapping it in another `Dialog` creates an outer root with no content owned
+by that root, which Data Slot 1.x rejects.
+
+```astro live
+---
+import {
+ Command,
+ CommandDialog,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from "@/components/ui/command"
+import { DialogTrigger } from "@/components/ui/dialog"
+---
+
+
+ Quick actions
+
+
+
+ Profile
+ Settings
+
+
+
+```
+
+Use native `autofocus` on a dialog's `CommandInput` so Data Slot places initial
+focus in the search field. Leave it off standalone command menus.
+
## Examples
### Basic
@@ -171,7 +204,7 @@ import {
Search for a command to run...
-
+
No results found.
diff --git a/src/content/pages/components/hover-card.mdx b/src/content/pages/components/hover-card.mdx
index 874c03247..29ae1ca67 100644
--- a/src/content/pages/components/hover-card.mdx
+++ b/src/content/pages/components/hover-card.mdx
@@ -152,6 +152,16 @@ keyboard interactions. The `open` prop enables controlled mode: interactions
request changes but do not update the state themselves. Dispatch `hover-card:set`
with `{ detail: { open: false } }` (or `true`) on the root to update it.
+## Content mounting
+
+Data Slot's recommended `"lazy"` strategy is the default: closed content is
+retained but detached from the document. Fulldev initializes nested Data Slot
+components inside that retained content too.
+
+Use `mountStrategy="eager"` when an integration needs to query closed content
+through the document. Both strategies include content in server-rendered HTML;
+neither adds a no-JavaScript fallback.
+
## API Reference
See the [GitHub source code](https://github.com/fulldotdev/ui/tree/main/src/components/ui/hover-card) for more information on props.
diff --git a/src/content/pages/components/navigation-menu.mdx b/src/content/pages/components/navigation-menu.mdx
index c49920a94..9d0d49ba0 100644
--- a/src/content/pages/components/navigation-menu.mdx
+++ b/src/content/pages/components/navigation-menu.mdx
@@ -187,6 +187,16 @@ NavigationMenu
- Keep the content panel layout inside `NavigationMenuContent` simple and
list-like so keyboard navigation stays predictable.
+## Content mounting
+
+Data Slot's recommended `"lazy"` strategy is the default: closed content is
+retained but detached from the document. Fulldev initializes nested Data Slot
+components inside that retained content too.
+
+Use `mountStrategy="eager"` when an integration needs to query closed content
+through the document. Both strategies include content in server-rendered HTML;
+neither adds a no-JavaScript fallback.
+
## API Reference
See the [GitHub source code](https://github.com/fulldotdev/ui/tree/main/src/components/ui/navigation-menu) for more information on props.
diff --git a/src/content/pages/components/select.mdx b/src/content/pages/components/select.mdx
index 880044175..94d8cd4f2 100644
--- a/src/content/pages/components/select.mdx
+++ b/src/content/pages/components/select.mdx
@@ -271,6 +271,16 @@ import {
```
+## Content mounting
+
+Data Slot's recommended `"lazy"` strategy is the default: closed content is
+retained but detached from the document. Fulldev initializes nested Data Slot
+components inside that retained content too.
+
+Use `mountStrategy="eager"` when an integration needs to query closed content
+through the document. Both strategies include content in server-rendered HTML;
+neither adds a no-JavaScript fallback.
+
## API Reference
See the [GitHub source code](https://github.com/fulldotdev/ui/tree/main/src/components/ui/select) for more information on props.
diff --git a/src/content/pages/components/tooltip.mdx b/src/content/pages/components/tooltip.mdx
index b93d4a1b6..b972e4e6e 100644
--- a/src/content/pages/components/tooltip.mdx
+++ b/src/content/pages/components/tooltip.mdx
@@ -100,6 +100,16 @@ import {
```
+## Content mounting
+
+Data Slot's recommended `"lazy"` strategy is the default: closed content is
+retained but detached from the document. Fulldev initializes nested Data Slot
+components inside that retained content too.
+
+Use `mountStrategy="eager"` when an integration needs to query closed content
+through the document. Both strategies include content in server-rendered HTML;
+neither adds a no-JavaScript fallback.
+
## API Reference
See the [GitHub source code](https://github.com/fulldotdev/ui/tree/main/src/components/ui/tooltip) for more information on props.
diff --git a/src/content/pages/docs/installation.mdx b/src/content/pages/docs/installation.mdx
index bbb9a8363..a72762ed8 100644
--- a/src/content/pages/docs/installation.mdx
+++ b/src/content/pages/docs/installation.mdx
@@ -130,3 +130,30 @@ import { Button } from "@/components/ui/button"
At that point, you can follow the component pages directly and install only the
pieces you need.
+
+## Data Slot 1.x upgrades
+
+Interactive components require Data Slot 1.0.1 or newer within 1.x. Updating npm
+versions alone does not update component files previously copied by the registry.
+Reinstall the affected registry items and merge their source changes with your
+customizations.
+
+Components use Data Slot's own initialization and release their controllers before
+Astro's `ClientRouter` swaps the page. Component state is reinitialized on navigation;
+this integration does not preserve interactive state across `transition:persist`.
+
+Select, Tooltip, Hover Card and Navigation Menu now use Data Slot's recommended
+lazy mounting. Closed content is retained outside the document. This changes DOM
+queries compared with 0.2.x: use `mountStrategy="eager"` if custom code needs to
+query closed content. Nested Data Slot components initialize in either mode.
+
+`CommandDialog` already includes a Dialog root. Use its `trigger` slot instead of
+wrapping it in another Dialog. See the [Command example](/components/command/#command-dialog).
+
+Command inputs inside dialogs should use native `autofocus` to receive initial
+focus. Standalone command inputs leave page focus unchanged. Slider now follows
+Data Slot's centered thumb default; use `thumbAlignment="edge"` to retain edge
+alignment. Tabs triggers and panels require an explicit `value`.
+
+Buttons and Tabs triggers default to `type="button"`, matching shadcn controls.
+Use `type="submit"` explicitly for form submission.
diff --git a/tests/clipboard.spec.ts b/tests/clipboard.spec.ts
new file mode 100644
index 000000000..598c28700
--- /dev/null
+++ b/tests/clipboard.spec.ts
@@ -0,0 +1,95 @@
+import { expect, test } from "@playwright/test"
+
+test.describe("documentation clipboard controls", () => {
+ test("code blocks initialize once and show success only after copying", async ({
+ page,
+ }) => {
+ await page.addInitScript(() => {
+ Object.defineProperty(navigator, "clipboard", {
+ configurable: true,
+ value: {
+ writeText: async (value: string) => {
+ const state = window as Window & {
+ copiedText?: string
+ copyCalls?: number
+ }
+ state.copiedText = value
+ state.copyCalls = (state.copyCalls ?? 0) + 1
+ },
+ },
+ })
+ })
+ await page.goto("/components/button/")
+
+ const preCount = await page
+ .locator("[data-slot='typography'] > .docs-code-block > pre")
+ .count()
+ await page.evaluate(() => {
+ for (let index = 0; index < 3; index += 1)
+ document.dispatchEvent(new Event("astro:page-load"))
+ })
+ await expect(page.locator(".docs-code-block")).toHaveCount(preCount)
+
+ const installButton = page
+ .locator("[id^='live-code-copy-install-']")
+ .first()
+ await installButton.click()
+ await expect(installButton.locator("[data-copy-icon]")).toHaveClass(
+ /hidden/
+ )
+ await expect(installButton.locator("[data-check-icon]")).not.toHaveClass(
+ /hidden/
+ )
+
+ const button = page.locator(".docs-code-copy").first()
+ await button.click()
+ await expect(button.locator("[data-copy-icon]")).toHaveClass(/hidden/)
+ await expect(button.locator("[data-check-icon]")).not.toHaveClass(/hidden/)
+ await expect
+ .poll(() =>
+ page.evaluate(
+ () => (window as Window & { copyCalls?: number }).copyCalls
+ )
+ )
+ .toBe(2)
+ await expect
+ .poll(() =>
+ page.evaluate(
+ () => (window as Window & { copiedText?: string }).copiedText
+ )
+ )
+ .not.toBe("")
+ })
+
+ test("failed clipboard writes leave the retry state unchanged", async ({
+ page,
+ }) => {
+ await page.addInitScript(() => {
+ Object.defineProperty(navigator, "clipboard", {
+ configurable: true,
+ value: {
+ writeText: async () => {
+ throw new Error("Clipboard unavailable")
+ },
+ },
+ })
+ })
+ await page.goto("/components/button/")
+
+ const installButton = page
+ .locator("[id^='live-code-copy-install-']")
+ .first()
+ await installButton.click()
+ await expect(installButton.locator("[data-copy-icon]")).not.toHaveClass(
+ /hidden/
+ )
+ await expect(installButton.locator("[data-check-icon]")).toHaveClass(
+ /hidden/
+ )
+
+ const button = page.locator(".docs-code-copy").first()
+ await button.click()
+ await expect(button.locator("[data-copy-icon]")).not.toHaveClass(/hidden/)
+ await expect(button.locator("[data-check-icon]")).toHaveClass(/hidden/)
+ })
+})
diff --git a/tests/data-slot.spec.ts b/tests/data-slot.spec.ts
new file mode 100644
index 000000000..12d41db58
--- /dev/null
+++ b/tests/data-slot.spec.ts
@@ -0,0 +1,347 @@
+import { expect, test, type Page } from "@playwright/test"
+
+const demo = (page: Page) => page.locator(".live-code-layout").first()
+
+async function open(page: Page, name: string) {
+ await page.goto(`/components/${name}/`)
+ await expect(
+ demo(page).getByRole("tab", { name: "Preview", exact: true })
+ ).toHaveAttribute("aria-selected", "true")
+ // Astro fires this after client navigation. Repeated initialization must not
+ // double-bind controls or lose content that has been moved into a portal.
+ await page.evaluate(() => {
+ for (let i = 0; i < 3; i++)
+ document.dispatchEvent(new Event("astro:page-load"))
+ })
+}
+
+test.beforeEach(async ({ page }) => {
+ page.on("pageerror", (error) => {
+ throw error
+ })
+})
+
+for (const [name, slot] of [
+ ["dialog", "dialog"],
+ ["sheet", "dialog"],
+ ["popover", "popover"],
+]) {
+ test(`${name}: pointer, keyboard, Escape, outside dismissal and repeated opening`, async ({
+ page,
+ isMobile,
+ }) => {
+ await open(page, name)
+ const trigger = demo(page).locator(`[data-slot="${slot}-trigger"]`)
+ const content = page.locator(`[data-slot="${slot}-content"]:visible`)
+ for (let i = 0; i < 3; i++) {
+ if (isMobile) await trigger.tap()
+ else await trigger.click()
+ await expect(content).toBeVisible()
+ await page.keyboard.press("Escape")
+ await expect(content).toHaveCount(0)
+ }
+ await trigger.press("Enter")
+ await expect(content).toBeVisible()
+ await page.keyboard.press("Escape")
+ await expect(content).toHaveCount(0)
+ await expect(trigger).toBeFocused()
+ await trigger.press("Enter")
+ await expect(content).toBeVisible()
+ if (slot === "dialog") {
+ await page.keyboard.press("Shift+Tab")
+ await expect
+ .poll(() =>
+ content.evaluate((el) => el.contains(document.activeElement))
+ )
+ .toBe(true)
+ await page.keyboard.press("Tab")
+ await expect
+ .poll(() =>
+ content.evaluate((el) => el.contains(document.activeElement))
+ )
+ .toBe(true)
+ }
+ if (isMobile) await page.touchscreen.tap(2, 2)
+ else await page.mouse.click(2, 2)
+ await expect(content).toHaveCount(0)
+ await expect
+ .poll(() => page.evaluate(() => document.documentElement.style.overflow))
+ .not.toBe("hidden")
+ })
+}
+
+test("alert dialog: cancel focus, blocking outside click, confirmation and reopening", async ({
+ page,
+}) => {
+ await open(page, "alert-dialog")
+ const trigger = demo(page).getByRole("button", { name: "Show Dialog" })
+ await trigger.press("Enter")
+ const dialog = page.getByRole("alertdialog")
+ await expect(dialog.getByRole("button", { name: "Cancel" })).toBeFocused()
+ await page.mouse.click(2, 2)
+ await expect(dialog).toBeVisible()
+ await dialog.getByRole("button", { name: "Cancel" }).click()
+ await expect(dialog).toBeHidden()
+ await expect(trigger).toBeFocused()
+ await trigger.press("Enter")
+ await dialog.getByRole("button", { name: "Continue" }).click()
+ // Data Slot actions intentionally leave async confirmation to the consumer.
+ await expect(dialog).toBeVisible()
+ await page.keyboard.press("Escape")
+ await expect(dialog).toBeHidden()
+})
+
+test("accordion: exclusive expansion and keyboard navigation", async ({
+ page,
+}) => {
+ await open(page, "accordion")
+ const triggers = demo(page).locator('[data-slot="accordion-trigger"]')
+ await triggers.nth(0).click()
+ await expect(triggers.nth(0)).toHaveAttribute("aria-expanded", "true")
+ await triggers.nth(0).press("ArrowDown")
+ await expect(triggers.nth(1)).toBeFocused()
+ await page.keyboard.press("Enter")
+ await expect(triggers.nth(1)).toHaveAttribute("aria-expanded", "true")
+ await expect(triggers.nth(0)).toHaveAttribute("aria-expanded", "false")
+})
+
+test("collapsible: repeated pointer and keyboard toggles", async ({ page }) => {
+ await open(page, "collapsible")
+ const trigger = demo(page).getByRole("button", { name: "Toggle details" })
+ const content = demo(page).locator('[data-slot="collapsible-content"]')
+ await trigger.click()
+ await expect(content).toBeVisible()
+ await trigger.press("Space")
+ await expect(content).toBeHidden()
+ await trigger.press("Enter")
+ await expect(content).toBeVisible()
+})
+
+test("tabs: nested demo tabs retain independent keyboard selection", async ({
+ page,
+}) => {
+ await open(page, "tabs")
+ const account = demo(page).getByRole("tab", { name: "Account", exact: true })
+ const password = demo(page).getByRole("tab", {
+ name: "Password",
+ exact: true,
+ })
+ await account.press("ArrowRight")
+ await expect(password).toHaveAttribute("aria-selected", "true")
+ await expect(
+ demo(page).getByRole("tab", { name: "Preview", exact: true })
+ ).toHaveAttribute("aria-selected", "true")
+ await password.press("Home")
+ await expect(account).toHaveAttribute("aria-selected", "true")
+})
+
+test("select: lazy content, keyboard selection, typeahead and disabled controls", async ({
+ page,
+}) => {
+ await open(page, "select")
+ const root = demo(page).locator('[data-slot="select"]')
+ await expect(root.locator('[data-slot="select-item"]')).toHaveCount(0)
+ const trigger = root.getByRole("combobox")
+ await trigger.press("ArrowDown")
+ await page.keyboard.press("b")
+ await page.keyboard.press("Enter")
+ await expect(trigger).toContainText("Banana")
+ await expect(trigger).toBeFocused()
+ await trigger.click()
+ await page.getByRole("option", { name: "Apple", exact: true }).click()
+ await expect(trigger).toContainText("Apple")
+ await expect(
+ page.getByRole("combobox").filter({ hasText: "Unavailable" })
+ ).toBeDisabled()
+})
+
+test("combobox: filtering, keyboard selection, clear and empty state", async ({
+ page,
+}) => {
+ await open(page, "combobox")
+ const input = demo(page).getByRole("combobox")
+ await input.fill("Astro")
+ await expect(
+ page.getByRole("option", { name: "Astro", exact: true })
+ ).toBeVisible()
+ await input.press("ArrowDown")
+ await input.press("Enter")
+ await expect(input).toHaveValue("Astro")
+ await input.fill("zzzzzzzzzz")
+ await expect(
+ page.locator('[data-slot="combobox-empty"]:visible')
+ ).toBeVisible()
+ await input.press("Escape")
+ await expect(
+ demo(page).locator('[data-slot="combobox-content"]')
+ ).toBeHidden()
+})
+
+test("dropdown menu: keyboard navigation and selection dismissal", async ({
+ page,
+}) => {
+ await open(page, "dropdown-menu")
+ const trigger = demo(page).getByRole("button", { name: "Open menu" })
+ await trigger.press("ArrowDown")
+ await expect(page.getByRole("menu")).toBeFocused()
+ await page.keyboard.press("ArrowDown")
+ await expect(
+ page.getByRole("menuitem", { name: /Profile/ }).first()
+ ).toBeFocused()
+ await page.keyboard.press("ArrowDown")
+ await expect(
+ page.getByRole("menuitem", { name: /Billing/ }).first()
+ ).toBeFocused()
+ await page.keyboard.press("Enter")
+ await expect(page.getByRole("menu")).toHaveCount(0)
+ await expect(trigger).toBeFocused()
+ await trigger.click()
+ await page.keyboard.press("Escape")
+ await expect(trigger).toHaveAttribute("aria-expanded", "false")
+})
+
+test("navigation menu: lazy links, keyboard opening and focus restoration", async ({
+ page,
+}) => {
+ await open(page, "navigation-menu")
+ const trigger = demo(page).getByRole("button", { name: "Getting started" })
+ await expect(
+ demo(page).locator('[data-slot="navigation-menu-content"]')
+ ).toHaveCount(0)
+ await trigger.press("Enter")
+ const content = page.locator('[data-slot="navigation-menu-content"]:visible')
+ await expect(content).toBeVisible()
+ await page.keyboard.press("Escape")
+ await expect(content).toHaveCount(0)
+ await expect(trigger).toBeFocused()
+})
+
+for (const name of ["tooltip", "hover-card"]) {
+ test(`${name}: lazy content, keyboard focus and Escape`, async ({
+ page,
+ browserName,
+ }) => {
+ await open(page, name)
+ const trigger = demo(page).locator(`[data-slot="${name}-trigger"]`)
+ await expect(
+ demo(page).locator(`[data-slot="${name}-content"]`)
+ ).toHaveCount(0)
+ await trigger.focus()
+ await page.keyboard.press(
+ browserName === "webkit" ? "Alt+Shift+Tab" : "Shift+Tab"
+ )
+ await page.keyboard.press(browserName === "webkit" ? "Alt+Tab" : "Tab")
+ const content = page.locator(`[data-slot="${name}-content"]:visible`)
+ await expect(content).toBeVisible()
+ await page.keyboard.press("Escape")
+ await expect(content).toHaveCount(0)
+ await expect(trigger).toBeFocused()
+ })
+}
+
+test("radio group: keyboard selection and roving focus", async ({ page }) => {
+ await open(page, "radio-group")
+ const radios = demo(page).getByRole("radio")
+ await radios.nth(0).press("ArrowDown")
+ await expect(radios.nth(1)).toBeChecked()
+ await expect(radios.nth(1)).toBeFocused()
+ await expect(radios.nth(0)).not.toBeChecked()
+})
+
+test("slider: keyboard bounds and pointer value changes", async ({ page }) => {
+ await open(page, "slider")
+ const slider = demo(page).getByRole("slider")
+ await slider.press("ArrowRight")
+ await expect(slider).toHaveAttribute("aria-valuenow", "34")
+ await slider.press("End")
+ await expect(slider).toHaveAttribute("aria-valuenow", "100")
+ await slider.press("Home")
+ await expect(slider).toHaveAttribute("aria-valuenow", "0")
+ await demo(page).locator('[data-slot="slider-track"]').click()
+ await expect(slider).not.toHaveAttribute("aria-valuenow", "0")
+})
+
+test("switch: click and Space toggle once after repeated initialization", async ({
+ page,
+}) => {
+ await open(page, "switch")
+ const control = demo(page).getByRole("switch")
+ await control.click()
+ await expect(control).toBeChecked()
+ await control.press("Space")
+ await expect(control).not.toBeChecked()
+})
+
+test("toggle: pointer and keyboard pressed state", async ({ page }) => {
+ await open(page, "toggle")
+ const toggle = demo(page).getByRole("button", { name: "Toggle bold" })
+ await toggle.click()
+ await expect(toggle).toHaveAttribute("aria-pressed", "true")
+ await toggle.press("Space")
+ await expect(toggle).toHaveAttribute("aria-pressed", "false")
+})
+
+test("command: new trigger slot, nested command filtering and dismissal", async ({
+ page,
+}) => {
+ await open(page, "command")
+ await expect(page.getByPlaceholder("Search shortcuts...")).not.toBeFocused()
+ await page
+ .getByRole("button", { name: "Quick actions", exact: true })
+ .press("Enter")
+ const dialog = page.getByRole("dialog", {
+ name: "Quick actions",
+ exact: true,
+ })
+ await expect(dialog).toBeVisible()
+ const input = dialog.getByRole("combobox")
+ await expect(input).toBeFocused()
+ await input.fill("zzzzzzzz")
+ await expect(dialog.getByRole("option")).toHaveCount(0)
+ await input.fill("Settings")
+ await expect(
+ dialog.getByRole("option", { name: "Settings", exact: true })
+ ).toBeVisible()
+ await input.press("Escape")
+ await expect(dialog).toBeHidden()
+})
+
+test("sidebar: mobile nested search, focus restoration and navigation reinitialization", async ({
+ page,
+ isMobile,
+}) => {
+ await open(page, "dialog")
+ for (let i = 0; i < 2; i++) {
+ if (isMobile)
+ await page
+ .getByRole("button", { name: "Toggle Sidebar", exact: true })
+ .click()
+ const search = page
+ .getByRole("button", { name: /Search/ })
+ .filter({ visible: true })
+ .first()
+ await search.press("Enter")
+ const dialog = page.getByRole("dialog", { name: "Search", exact: true })
+ await expect(dialog).toBeVisible()
+ await expect(dialog.getByRole("combobox")).toBeFocused()
+ await dialog.getByRole("combobox").fill("zzzzzzzzzzzz")
+ await expect(dialog.getByRole("option")).toHaveCount(0)
+ await page.keyboard.press("Escape")
+ await expect(dialog).toBeHidden()
+ await expect(search).toBeFocused()
+ if (isMobile) {
+ await expect(
+ page.getByRole("dialog", { name: "Sidebar", exact: true })
+ ).toBeVisible()
+ await page.keyboard.press("Escape")
+ await expect(
+ page.getByRole("dialog", { name: "Sidebar", exact: true })
+ ).toBeHidden()
+ }
+ await page.goto("/components/select/")
+ await page.goBack()
+ await expect(
+ demo(page).getByRole("button", { name: "Edit Profile" })
+ ).toBeVisible()
+ }
+})
diff --git a/tests/visual.spec.ts b/tests/visual.spec.ts
index 89813a561..447ce686d 100644
--- a/tests/visual.spec.ts
+++ b/tests/visual.spec.ts
@@ -21,3 +21,24 @@ for (const path of pages) {
await argosScreenshot(page, path === "/" ? "home" : path.slice(1))
})
}
+
+test("command palette open", async ({ page }) => {
+ await page.goto("/components/command/")
+ if ((page.viewportSize()?.width ?? 1440) < 768) {
+ await page
+ .getByRole("button", { name: "Toggle Sidebar", exact: true })
+ .click()
+ await expect(
+ page.getByRole("dialog", { name: "Sidebar", exact: true })
+ ).toBeVisible()
+ }
+ await page
+ .getByRole("button", { name: /Search/ })
+ .filter({ visible: true })
+ .first()
+ .click()
+ const dialog = page.getByRole("dialog", { name: "Search", exact: true })
+ await expect(dialog).toBeVisible()
+ await expect(dialog.getByRole("combobox")).toBeFocused()
+ await argosScreenshot(page, "command-palette-open", { fullPage: false })
+})