From bc032dc660ad75146aeff51a2eaf17f66fd9a682 Mon Sep 17 00:00:00 2001 From: Sil Date: Sat, 26 Sep 2026 16:29:37 +0200 Subject: [PATCH 1/9] Upgrade Data Slot primitives and registry to 1.0.1 --- .changeset/data-slot-one.md | 8 + package.json | 36 +-- pnpm-lock.yaml | 223 +++++++++--------- public/r/accordion.json | 2 +- public/r/alert-dialog.json | 2 +- public/r/collapsible.json | 2 +- public/r/combobox.json | 5 +- public/r/command.json | 2 +- public/r/dialog.json | 2 +- public/r/dropdown-menu.json | 2 +- public/r/hover-card.json | 6 +- public/r/navigation-menu.json | 4 +- public/r/popover.json | 2 +- public/r/radio-group.json | 2 +- public/r/registry.json | 41 ++-- public/r/select.json | 4 +- public/r/sheet.json | 2 +- public/r/sidebar.json | 2 +- public/r/slider.json | 2 +- public/r/switch.json | 2 +- public/r/tabs.json | 2 +- public/r/toggle.json | 2 +- public/r/tooltip.json | 4 +- registry.json | 45 ++-- src/components/ui/combobox/combobox.astro | 8 +- src/components/ui/hover-card/hover-card.astro | 8 +- .../ui/navigation-menu/navigation-menu.astro | 3 + src/components/ui/select/select.astro | 3 + src/components/ui/tooltip/tooltip.astro | 3 + src/content/pages/components/hover-card.mdx | 11 + .../pages/components/navigation-menu.mdx | 11 + src/content/pages/components/select.mdx | 11 + src/content/pages/components/tooltip.mdx | 11 + 33 files changed, 271 insertions(+), 202 deletions(-) create mode 100644 .changeset/data-slot-one.md diff --git a/.changeset/data-slot-one.md b/.changeset/data-slot-one.md new file mode 100644 index 000000000..9cf62fa82 --- /dev/null +++ b/.changeset/data-slot-one.md @@ -0,0 +1,8 @@ +--- +"fulldev-ui": minor +--- + +Upgrade all Data Slot primitives and registry dependencies to 1.0.1. Preserve +connected hidden content by default for Select, Tooltip, Hover Card and Navigation +Menu, with an explicit mountStrategy prop for lazy mounting. Discover nested +comboboxes and hover cards in retained content without duplicate initialization. diff --git a/package.json b/package.json index 40df64235..173388d2a 100644 --- a/package.json +++ b/package.json @@ -72,24 +72,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/pnpm-lock.yaml b/pnpm-lock.yaml index 0cc9ac3f9..624e971dd 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==} @@ -3809,10 +3809,6 @@ packages: tmp-promise@3.0.3: resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} - tmp@0.2.5: - resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} - engines: {node: '>=14.14'} - tmp@0.2.7: resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} engines: {node: '>=14.14'} @@ -4835,75 +4831,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: @@ -8602,10 +8598,7 @@ snapshots: tmp-promise@3.0.3: dependencies: - tmp: 0.2.5 - optional: true - - tmp@0.2.5: + tmp: 0.2.7 optional: true tmp@0.2.7: {} diff --git a/public/r/accordion.json b/public/r/accordion.json index c72d0a559..f6571fe7c 100644 --- a/public/r/accordion.json +++ b/public/r/accordion.json @@ -4,7 +4,7 @@ "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": [ diff --git a/public/r/alert-dialog.json b/public/r/alert-dialog.json index 33e3b4c60..254d0fec4 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" diff --git a/public/r/collapsible.json b/public/r/collapsible.json index 499610926..d7bd5e488 100644 --- a/public/r/collapsible.json +++ b/public/r/collapsible.json @@ -4,7 +4,7 @@ "title": "Collapsible", "description": "An interactive component which expands/collapses a panel.", "dependencies": [ - "@data-slot/collapsible" + "@data-slot/collapsible@^1.0.1" ], "files": [ { diff --git a/public/r/combobox.json b/public/r/combobox.json index dd913b851..cd4abd64c 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,7 +14,7 @@ "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" }, { diff --git a/public/r/command.json b/public/r/command.json index fc464541d..f0f06bd08 100644 --- a/public/r/command.json +++ b/public/r/command.json @@ -4,7 +4,7 @@ "title": "Command", "description": "Command menu for search and quick actions.", "dependencies": [ - "@data-slot/command", + "@data-slot/command@^1.0.1", "@lucide/astro" ], "registryDependencies": [ diff --git a/public/r/dialog.json b/public/r/dialog.json index 73fce0fd3..d8a6cffa7 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": [ diff --git a/public/r/dropdown-menu.json b/public/r/dropdown-menu.json index 3d80de76e..717c6ea37 100644 --- a/public/r/dropdown-menu.json +++ b/public/r/dropdown-menu.json @@ -4,7 +4,7 @@ "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": [ diff --git a/public/r/hover-card.json b/public/r/hover-card.json index 67dc7099e..2e257bda8 100644 --- a/public/r/hover-card.json +++ b/public/r/hover-card.json @@ -4,13 +4,13 @@ "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 = \"eager\",\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" }, { diff --git a/public/r/navigation-menu.json b/public/r/navigation-menu.json index a41039a40..530a8b1cb 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 = \"eager\",\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" }, { diff --git a/public/r/popover.json b/public/r/popover.json index f63bdd151..e57126038 100644 --- a/public/r/popover.json +++ b/public/r/popover.json @@ -4,7 +4,7 @@ "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": [ { diff --git a/public/r/radio-group.json b/public/r/radio-group.json index ef137f733..596dbd35e 100644 --- a/public/r/radio-group.json +++ b/public/r/radio-group.json @@ -4,7 +4,7 @@ "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": [ { diff --git a/public/r/registry.json b/public/r/registry.json index e01ccf999..e697986ce 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" @@ -365,7 +365,7 @@ ], "docs": "https://ui.full.dev/components/collapsible/", "dependencies": [ - "@data-slot/collapsible" + "@data-slot/collapsible@^1.0.1" ], "files": [ { @@ -396,7 +396,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,7 +464,7 @@ ], "docs": "https://ui.full.dev/components/command/", "dependencies": [ - "@data-slot/command", + "@data-slot/command@^1.0.1", "@lucide/astro" ], "registryDependencies": [ @@ -522,7 +523,7 @@ ], "docs": "https://ui.full.dev/components/dialog/", "dependencies": [ - "@data-slot/dialog", + "@data-slot/dialog@^1.0.1", "@lucide/astro" ], "registryDependencies": [ @@ -585,7 +586,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 +801,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": [ { @@ -1131,7 +1132,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 +1219,7 @@ ], "docs": "https://ui.full.dev/components/popover/", "dependencies": [ - "@data-slot/popover" + "@data-slot/popover@^1.0.1" ], "files": [ { @@ -1293,7 +1294,7 @@ ], "docs": "https://ui.full.dev/components/radio-group/", "dependencies": [ - "@data-slot/radio-group" + "@data-slot/radio-group@^1.0.1" ], "files": [ { @@ -1343,7 +1344,7 @@ ], "docs": "https://ui.full.dev/components/select/", "dependencies": [ - "@data-slot/select", + "@data-slot/select@^1.0.1", "@lucide/astro" ], "files": [ @@ -1447,7 +1448,7 @@ ], "docs": "https://ui.full.dev/components/sheet/", "dependencies": [ - "@data-slot/dialog", + "@data-slot/dialog@^1.0.1", "@lucide/astro" ], "registryDependencies": [ @@ -1503,7 +1504,7 @@ ], "docs": "https://ui.full.dev/components/sidebar/", "dependencies": [ - "@data-slot/tooltip", + "@data-slot/tooltip@^1.0.1", "@lucide/astro" ], "registryDependencies": [ @@ -1624,7 +1625,7 @@ ], "docs": "https://ui.full.dev/components/slider/", "dependencies": [ - "@data-slot/slider" + "@data-slot/slider@^1.0.1" ], "files": [ { @@ -1690,7 +1691,7 @@ ], "docs": "https://ui.full.dev/components/switch/", "dependencies": [ - "@data-slot/switch" + "@data-slot/switch@^1.0.1" ], "files": [ { @@ -1761,7 +1762,7 @@ ], "docs": "https://ui.full.dev/components/tabs/", "dependencies": [ - "@data-slot/tabs" + "@data-slot/tabs@^1.0.1" ], "files": [ { @@ -1836,7 +1837,7 @@ ], "docs": "https://ui.full.dev/components/toggle/", "dependencies": [ - "@data-slot/toggle" + "@data-slot/toggle@^1.0.1" ], "files": [ { @@ -1883,7 +1884,7 @@ ], "docs": "https://ui.full.dev/components/tooltip/", "dependencies": [ - "@data-slot/tooltip" + "@data-slot/tooltip@^1.0.1" ], "files": [ { diff --git a/public/r/select.json b/public/r/select.json index 38e9cb3d5..2a061bf05 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 = \"eager\",\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" }, { diff --git a/public/r/sheet.json b/public/r/sheet.json index ecf90e06e..5d36b995e 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": [ 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..76ff68c7a 100644 --- a/public/r/slider.json +++ b/public/r/slider.json @@ -4,7 +4,7 @@ "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": [ { diff --git a/public/r/switch.json b/public/r/switch.json index 91c66ac23..78c6d0426 100644 --- a/public/r/switch.json +++ b/public/r/switch.json @@ -4,7 +4,7 @@ "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": [ { diff --git a/public/r/tabs.json b/public/r/tabs.json index 432876983..1318c485c 100644 --- a/public/r/tabs.json +++ b/public/r/tabs.json @@ -4,7 +4,7 @@ "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": [ { diff --git a/public/r/toggle.json b/public/r/toggle.json index 2d1b9ad59..7db7f679b 100644 --- a/public/r/toggle.json +++ b/public/r/toggle.json @@ -4,7 +4,7 @@ "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": [ { diff --git a/public/r/tooltip.json b/public/r/tooltip.json index 2d881c258..60e8f9dee 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 = \"eager\",\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" }, { diff --git a/registry.json b/registry.json index 2eaed2dec..f78a5a212 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": [ { @@ -328,7 +328,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 +355,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 +419,7 @@ "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"], "registryDependencies": ["@fulldev/dialog"], "files": [ { @@ -467,7 +471,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 +527,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 +721,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", @@ -1011,7 +1018,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 +1096,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 +1165,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 +1207,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 +1302,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 +1350,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 +1466,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 +1522,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 +1587,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 +1656,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 +1697,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", diff --git a/src/components/ui/combobox/combobox.astro b/src/components/ui/combobox/combobox.astro index 7b5f0a54b..0d78830e8 100644 --- a/src/components/ui/combobox/combobox.astro +++ b/src/components/ui/combobox/combobox.astro @@ -68,12 +68,14 @@ const { \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 254d0fec4..a148e5f79 100644 --- a/public/r/alert-dialog.json +++ b/public/r/alert-dialog.json @@ -7,12 +7,13 @@ "@data-slot/alert-dialog@^1.0.1" ], "registryDependencies": [ - "@fulldev/button" + "@fulldev/button", + "@fulldev/data-slot" ], "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/collapsible.json b/public/r/collapsible.json index d7bd5e488..b378ed59b 100644 --- a/public/r/collapsible.json +++ b/public/r/collapsible.json @@ -6,10 +6,13 @@ "dependencies": [ "@data-slot/collapsible@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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 cd4abd64c..5921723d8 100644 --- a/public/r/combobox.json +++ b/public/r/combobox.json @@ -9,12 +9,13 @@ "@lucide/astro" ], "registryDependencies": [ - "@fulldev/input-group" + "@fulldev/input-group", + "@fulldev/data-slot" ], "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" }, { diff --git a/public/r/command.json b/public/r/command.json index f0f06bd08..d7069fbac 100644 --- a/public/r/command.json +++ b/public/r/command.json @@ -8,17 +8,18 @@ "@lucide/astro" ], "registryDependencies": [ - "@fulldev/dialog" + "@fulldev/dialog", + "@fulldev/data-slot" ], "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/data-slot.json b/public/r/data-slot.json new file mode 100644 index 000000000..a7bfee53f --- /dev/null +++ b/public/r/data-slot.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "data-slot", + "title": "Data Slot lifecycle", + "description": "Shared Data Slot initialization and Astro page-swap cleanup.", + "dependencies": [ + "@data-slot/core@^1.0.1" + ], + "files": [ + { + "path": "src/lib/data-slot.ts", + "content": "import { getRoots, hasRootBinding } from \"@data-slot/core\"\n\ntype Controller = { destroy(): void }\n\n/** Bind new roots once and release outgoing controllers before Astro swaps pages. */\nexport function initializeDataSlot(\n slot: string,\n create: (root: HTMLElement) => Controller | undefined\n) {\n const controllers = new Map()\n\n const initialize = () => {\n for (const root of getRoots(document, slot)) {\n if (hasRootBinding(root, `@data-slot/${slot}`)) continue\n const controller = create(root)\n if (controller) controllers.set(root, controller)\n }\n }\n\n initialize()\n document.addEventListener(\"astro:page-load\", initialize)\n document.addEventListener(\"astro:before-swap\", (event) => {\n const nextDocument = (event as Event & { newDocument: Document })\n .newDocument\n const persisted = new Set(\n Array.from(\n nextDocument.querySelectorAll(\"[data-astro-transition-persist]\")\n ).map((element) => element.getAttribute(\"data-astro-transition-persist\"))\n )\n for (const [root, controller] of controllers) {\n const persist = root.closest(\"[data-astro-transition-persist]\")\n if (\n persist &&\n persisted.has(persist.getAttribute(\"data-astro-transition-persist\"))\n )\n continue\n controller.destroy()\n controllers.delete(root)\n }\n })\n}\n", + "type": "registry:lib" + } + ], + "type": "registry:lib" +} \ No newline at end of file diff --git a/public/r/dialog.json b/public/r/dialog.json index d8a6cffa7..7744ff86b 100644 --- a/public/r/dialog.json +++ b/public/r/dialog.json @@ -8,12 +8,13 @@ "@lucide/astro" ], "registryDependencies": [ - "@fulldev/button" + "@fulldev/button", + "@fulldev/data-slot" ], "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/dropdown-menu.json b/public/r/dropdown-menu.json index 717c6ea37..da3be9bb0 100644 --- a/public/r/dropdown-menu.json +++ b/public/r/dropdown-menu.json @@ -7,10 +7,13 @@ "@data-slot/dropdown-menu@^1.0.1", "@lucide/astro" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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" }, { diff --git a/public/r/hover-card.json b/public/r/hover-card.json index 2e257bda8..55181e5a9 100644 --- a/public/r/hover-card.json +++ b/public/r/hover-card.json @@ -7,10 +7,13 @@ "@data-slot/hover-card@^1.0.1", "@data-slot/core@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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 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 = \"eager\",\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 = \"eager\",\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" }, { 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 530a8b1cb..b265ca335 100644 --- a/public/r/navigation-menu.json +++ b/public/r/navigation-menu.json @@ -7,10 +7,13 @@ "@data-slot/navigation-menu@^1.0.1", "@lucide/astro" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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 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 = \"eager\",\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 = \"eager\",\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" }, { diff --git a/public/r/popover.json b/public/r/popover.json index e57126038..fb6b0cef8 100644 --- a/public/r/popover.json +++ b/public/r/popover.json @@ -6,10 +6,13 @@ "dependencies": [ "@data-slot/popover@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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 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" }, { diff --git a/public/r/radio-group.json b/public/r/radio-group.json index 596dbd35e..738ce6809 100644 --- a/public/r/radio-group.json +++ b/public/r/radio-group.json @@ -6,10 +6,13 @@ "dependencies": [ "@data-slot/radio-group@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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 e697986ce..88ef7fc55 100644 --- a/public/r/registry.json +++ b/public/r/registry.json @@ -16,6 +16,9 @@ "@data-slot/accordion@^1.0.1", "@lucide/astro" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/accordion/accordion.astro", @@ -80,7 +83,8 @@ "@data-slot/alert-dialog@^1.0.1" ], "registryDependencies": [ - "@fulldev/button" + "@fulldev/button", + "@fulldev/data-slot" ], "files": [ { @@ -367,6 +371,9 @@ "dependencies": [ "@data-slot/collapsible@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/collapsible/collapsible.astro", @@ -401,7 +408,8 @@ "@lucide/astro" ], "registryDependencies": [ - "@fulldev/input-group" + "@fulldev/input-group", + "@fulldev/data-slot" ], "files": [ { @@ -468,7 +476,8 @@ "@lucide/astro" ], "registryDependencies": [ - "@fulldev/dialog" + "@fulldev/dialog", + "@fulldev/data-slot" ], "files": [ { @@ -527,7 +536,8 @@ "@lucide/astro" ], "registryDependencies": [ - "@fulldev/button" + "@fulldev/button", + "@fulldev/data-slot" ], "files": [ { @@ -589,6 +599,9 @@ "@data-slot/dropdown-menu@^1.0.1", "@lucide/astro" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/dropdown-menu/dropdown-menu.astro", @@ -804,6 +817,9 @@ "@data-slot/hover-card@^1.0.1", "@data-slot/core@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/hover-card/hover-card.astro", @@ -1135,6 +1151,9 @@ "@data-slot/navigation-menu@^1.0.1", "@lucide/astro" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/navigation-menu/navigation-menu.astro", @@ -1221,6 +1240,9 @@ "dependencies": [ "@data-slot/popover@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/popover/popover.astro", @@ -1296,6 +1318,9 @@ "dependencies": [ "@data-slot/radio-group@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/radio-group/radio-group.astro", @@ -1347,6 +1372,9 @@ "@data-slot/select@^1.0.1", "@lucide/astro" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/select/select.astro", @@ -1453,7 +1481,8 @@ ], "registryDependencies": [ "@fulldev/button", - "@fulldev/dialog" + "@fulldev/dialog", + "@fulldev/data-slot" ], "files": [ { @@ -1627,6 +1656,9 @@ "dependencies": [ "@data-slot/slider@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/slider/slider.astro", @@ -1693,6 +1725,9 @@ "dependencies": [ "@data-slot/switch@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/switch/switch.astro", @@ -1764,6 +1799,9 @@ "dependencies": [ "@data-slot/tabs@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/tabs/tabs.astro", @@ -1839,6 +1877,9 @@ "dependencies": [ "@data-slot/toggle@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/toggle/toggle.astro", @@ -1886,6 +1927,9 @@ "dependencies": [ "@data-slot/tooltip@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/tooltip/tooltip.astro", @@ -2077,6 +2121,9 @@ "ui" ], "docs": "https://ui.full.dev/components/layout/", + "dependencies": [ + "@lexingtonthemes/seo@^0.2.0" + ], "files": [ { "path": "src/components/ui/layout/layout.astro", @@ -4190,6 +4237,21 @@ "@fulldev/services-7", "@fulldev/sidebar-1" ] + }, + { + "name": "data-slot", + "type": "registry:lib", + "title": "Data Slot lifecycle", + "description": "Shared Data Slot initialization and Astro page-swap cleanup.", + "dependencies": [ + "@data-slot/core@^1.0.1" + ], + "files": [ + { + "path": "src/lib/data-slot.ts", + "type": "registry:lib" + } + ] } ] } diff --git a/public/r/select.json b/public/r/select.json index 2a061bf05..dc41e829f 100644 --- a/public/r/select.json +++ b/public/r/select.json @@ -7,10 +7,13 @@ "@data-slot/select@^1.0.1", "@lucide/astro" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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 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 = \"eager\",\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 = \"eager\",\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" }, { diff --git a/public/r/sheet.json b/public/r/sheet.json index 5d36b995e..0d9de4e65 100644 --- a/public/r/sheet.json +++ b/public/r/sheet.json @@ -9,12 +9,13 @@ ], "registryDependencies": [ "@fulldev/button", - "@fulldev/dialog" + "@fulldev/dialog", + "@fulldev/data-slot" ], "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..82b75394e 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 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/slider.json b/public/r/slider.json index 76ff68c7a..02d86195d 100644 --- a/public/r/slider.json +++ b/public/r/slider.json @@ -6,10 +6,13 @@ "dependencies": [ "@data-slot/slider@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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 \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] | 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 \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 78c6d0426..1669812d2 100644 --- a/public/r/switch.json +++ b/public/r/switch.json @@ -6,10 +6,13 @@ "dependencies": [ "@data-slot/switch@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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 1318c485c..d61bf01da 100644 --- a/public/r/tabs.json +++ b/public/r/tabs.json @@ -6,10 +6,13 @@ "dependencies": [ "@data-slot/tabs@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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" }, { diff --git a/public/r/toggle.json b/public/r/toggle.json index 7db7f679b..27a1ac6e0 100644 --- a/public/r/toggle.json +++ b/public/r/toggle.json @@ -6,10 +6,13 @@ "dependencies": [ "@data-slot/toggle@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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 60e8f9dee..e2ed351cf 100644 --- a/public/r/tooltip.json +++ b/public/r/tooltip.json @@ -6,10 +6,13 @@ "dependencies": [ "@data-slot/tooltip@^1.0.1" ], + "registryDependencies": [ + "@fulldev/data-slot" + ], "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 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 = \"eager\",\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 = \"eager\",\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" }, { diff --git a/registry.json b/registry.json index f78a5a212..8ecfece88 100644 --- a/registry.json +++ b/registry.json @@ -11,6 +11,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/accordion/", "dependencies": ["@data-slot/accordion@^1.0.1", "@lucide/astro"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/accordion/accordion.astro", @@ -68,7 +69,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/alert-dialog/", "dependencies": ["@data-slot/alert-dialog@^1.0.1"], - "registryDependencies": ["@fulldev/button"], + "registryDependencies": ["@fulldev/button", "@fulldev/data-slot"], "files": [ { "path": "src/components/ui/alert-dialog/alert-dialog.astro", @@ -329,6 +330,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/collapsible/", "dependencies": ["@data-slot/collapsible@^1.0.1"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/collapsible/collapsible.astro", @@ -360,7 +362,7 @@ "@data-slot/core@^1.0.1", "@lucide/astro" ], - "registryDependencies": ["@fulldev/input-group"], + "registryDependencies": ["@fulldev/input-group", "@fulldev/data-slot"], "files": [ { "path": "src/components/ui/combobox/combobox.astro", @@ -420,7 +422,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/command/", "dependencies": ["@data-slot/command@^1.0.1", "@lucide/astro"], - "registryDependencies": ["@fulldev/dialog"], + "registryDependencies": ["@fulldev/dialog", "@fulldev/data-slot"], "files": [ { "path": "src/components/ui/command/command.astro", @@ -472,7 +474,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/dialog/", "dependencies": ["@data-slot/dialog@^1.0.1", "@lucide/astro"], - "registryDependencies": ["@fulldev/button"], + "registryDependencies": ["@fulldev/button", "@fulldev/data-slot"], "files": [ { "path": "src/components/ui/dialog/dialog.astro", @@ -528,6 +530,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/dropdown-menu/", "dependencies": ["@data-slot/dropdown-menu@^1.0.1", "@lucide/astro"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/dropdown-menu/dropdown-menu.astro", @@ -725,6 +728,7 @@ "@data-slot/hover-card@^1.0.1", "@data-slot/core@^1.0.1" ], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/hover-card/hover-card.astro", @@ -1019,6 +1023,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/navigation-menu/", "dependencies": ["@data-slot/navigation-menu@^1.0.1", "@lucide/astro"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/navigation-menu/navigation-menu.astro", @@ -1097,6 +1102,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/popover/", "dependencies": ["@data-slot/popover@^1.0.1"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/popover/popover.astro", @@ -1166,6 +1172,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/radio-group/", "dependencies": ["@data-slot/radio-group@^1.0.1"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/radio-group/radio-group.astro", @@ -1208,6 +1215,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/select/", "dependencies": ["@data-slot/select@^1.0.1", "@lucide/astro"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/select/select.astro", @@ -1303,7 +1311,11 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/sheet/", "dependencies": ["@data-slot/dialog@^1.0.1", "@lucide/astro"], - "registryDependencies": ["@fulldev/button", "@fulldev/dialog"], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/dialog", + "@fulldev/data-slot" + ], "files": [ { "path": "src/components/ui/sheet/sheet.astro", @@ -1467,6 +1479,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/slider/", "dependencies": ["@data-slot/slider@^1.0.1"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/slider/slider.astro", @@ -1523,6 +1536,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/switch/", "dependencies": ["@data-slot/switch@^1.0.1"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/switch/switch.astro", @@ -1588,6 +1602,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/tabs/", "dependencies": ["@data-slot/tabs@^1.0.1"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/tabs/tabs.astro", @@ -1657,6 +1672,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/toggle/", "dependencies": ["@data-slot/toggle@^1.0.1"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/toggle/toggle.astro", @@ -1698,6 +1714,7 @@ "categories": ["ui"], "docs": "https://ui.full.dev/components/tooltip/", "dependencies": ["@data-slot/tooltip@^1.0.1"], + "registryDependencies": ["@fulldev/data-slot"], "files": [ { "path": "src/components/ui/tooltip/tooltip.astro", @@ -1883,6 +1900,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", @@ -3691,6 +3709,19 @@ "@fulldev/services-7", "@fulldev/sidebar-1" ] + }, + { + "name": "data-slot", + "type": "registry:lib", + "title": "Data Slot lifecycle", + "description": "Shared Data Slot initialization and Astro page-swap cleanup.", + "dependencies": ["@data-slot/core@^1.0.1"], + "files": [ + { + "path": "src/lib/data-slot.ts", + "type": "registry:lib" + } + ] } ] } diff --git a/scripts/check-data-slot-consumer.mjs b/scripts/check-data-slot-consumer.mjs new file mode 100644 index 000000000..7e1baace0 --- /dev/null +++ b/scripts/check-data-slot-consumer.mjs @@ -0,0 +1,151 @@ +import { spawn } from "node:child_process" +import { copyFile, mkdir, mkdtemp, readFile, writeFile } from "node:fs/promises" +import { createServer } from "node:http" +import { tmpdir } from "node:os" +import { join } from "node:path" + +const repo = new URL("../", import.meta.url) +const registry = JSON.parse( + await readFile(new URL("registry.json", repo), "utf8") +) +const affected = new Set( + registry.items + .filter((item) => + item.dependencies?.some((dep) => dep.startsWith("@data-slot/")) + ) + .map((item) => item.name) +) +let previousSize +while (previousSize !== affected.size) { + previousSize = affected.size + for (const item of registry.items) { + if ( + item.registryDependencies?.some((dep) => + affected.has(dep.replace("@fulldev/", "")) + ) + ) + affected.add(item.name) + } +} +const items = registry.items.filter( + (item) => + affected.has(item.name) && + ["registry:ui", "registry:block"].includes(item.type) +) +const dir = await mkdtemp(join(tmpdir(), "fulldev-data-slot-consumer-")) +const run = (args, cwd = dir) => + new Promise((resolve, reject) => { + const child = spawn("pnpm", args, { cwd, stdio: "inherit" }) + child.on("error", reject) + child.on("exit", (code) => + code === 0 + ? resolve() + : reject(new Error(`pnpm ${args.join(" ")} exited ${code}`)) + ) + }) + +const server = createServer(async (request, response) => { + const name = request.url?.match(/^\/r\/([a-z0-9-]+)\.json$/)?.[1] + if (!name) { + response.writeHead(404).end() + return + } + try { + const body = await readFile(new URL(`public/r/${name}.json`, repo)) + response.writeHead(200, { "Content-Type": "application/json" }).end(body) + } catch { + response.writeHead(404).end() + } +}) +await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)) +const port = server.address().port +try { + await mkdir(join(dir, "src/pages"), { recursive: true }) + await mkdir(join(dir, "src/styles"), { recursive: true }) + const pkg = JSON.parse(await readFile(new URL("package.json", repo), "utf8")) + await writeFile( + join(dir, "package.json"), + JSON.stringify( + { + name: "data-slot-consumer", + private: true, + type: "module", + packageManager: pkg.packageManager, + dependencies: Object.fromEntries( + ["astro", "tailwindcss", "@tailwindcss/vite"].map((name) => [ + name, + pkg.dependencies[name], + ]) + ), + devDependencies: { + "@astrojs/check": pkg.devDependencies["@astrojs/check"], + typescript: pkg.dependencies.typescript, + }, + }, + null, + 2 + ) + ) + const components = JSON.parse( + await readFile(new URL("components.json", repo), "utf8") + ) + components.registries = { + "@fulldev": `http://127.0.0.1:${port}/r/{name}.json`, + } + await writeFile( + join(dir, "components.json"), + JSON.stringify(components, null, 2) + ) + await writeFile( + join(dir, "tsconfig.json"), + JSON.stringify({ + extends: "astro/tsconfigs/strict", + compilerOptions: { baseUrl: ".", paths: { "@/*": ["src/*"] } }, + }) + ) + await writeFile( + join(dir, "astro.config.mjs"), + 'import {defineConfig} from "astro/config"; import tailwind from "@tailwindcss/vite"; export default defineConfig({vite:{plugins:[tailwind()]}});\n' + ) + await writeFile( + join(dir, "src/styles/global.css"), + '@import "tailwindcss";\n' + ) + await run(["install"]) + await run( + [ + "exec", + "shadcn", + "add", + "--cwd", + dir, + "--yes", + "--overwrite", + "@fulldev/init", + ...items.map((item) => `@fulldev/${item.name}`), + ], + repo + ) + for (const page of ["index", "next"]) + await copyFile( + new URL("tests/fixtures/data-slot-consumer.astro", repo), + join(dir, `src/pages/${page}.astro`) + ) + await run(["exec", "astro", "build"]) + await run(["exec", "astro", "check"]) + console.log( + `Consumer passed: ${items.length} affected components/blocks plus their registry dependencies, installed through shadcn into ${dir}` + ) +} finally { + await new Promise((resolve) => server.close(resolve)) +} +if (process.argv.includes("--serve")) + await run([ + "exec", + "astro", + "preview", + "--host", + "127.0.0.1", + "--port", + "4176", + ]) diff --git a/src/components/blocks/sidebar-1.astro b/src/components/blocks/sidebar-1.astro index 25cfebdab..36d6be67a 100644 --- a/src/components/blocks/sidebar-1.astro +++ b/src/components/blocks/sidebar-1.astro @@ -23,7 +23,7 @@ import { CommandList, CommandShortcut, } from "@/components/ui/command" -import { Dialog, DialogTrigger } from "@/components/ui/dialog" +import { DialogTrigger } from "@/components/ui/dialog" import { DropdownMenu, DropdownMenuContent, @@ -139,7 +139,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} + + ))} + + )) + } + + + diff --git a/src/components/ui/alert-dialog/alert-dialog.astro b/src/components/ui/alert-dialog/alert-dialog.astro index 24a1c7163..058219bcd 100644 --- a/src/components/ui/alert-dialog/alert-dialog.astro +++ b/src/components/ui/alert-dialog/alert-dialog.astro @@ -31,8 +31,9 @@ const { diff --git a/src/components/ui/collapsible/collapsible.astro b/src/components/ui/collapsible/collapsible.astro index bb715aab8..11756f23f 100644 --- a/src/components/ui/collapsible/collapsible.astro +++ b/src/components/ui/collapsible/collapsible.astro @@ -27,8 +27,9 @@ const { diff --git a/src/components/ui/combobox/combobox.astro b/src/components/ui/combobox/combobox.astro index 0d78830e8..826f92420 100644 --- a/src/components/ui/combobox/combobox.astro +++ b/src/components/ui/combobox/combobox.astro @@ -68,23 +68,13 @@ const { 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 { --- + diff --git a/src/components/ui/dialog/dialog.astro b/src/components/ui/dialog/dialog.astro index 00537d5f4..1e61dbf1d 100644 --- a/src/components/ui/dialog/dialog.astro +++ b/src/components/ui/dialog/dialog.astro @@ -34,8 +34,9 @@ const { diff --git a/src/components/ui/dropdown-menu/dropdown-menu.astro b/src/components/ui/dropdown-menu/dropdown-menu.astro index d802e624a..14750a42c 100644 --- a/src/components/ui/dropdown-menu/dropdown-menu.astro +++ b/src/components/ui/dropdown-menu/dropdown-menu.astro @@ -65,8 +65,9 @@ const defaultValuesAttr = diff --git a/src/components/ui/hover-card/hover-card.astro b/src/components/ui/hover-card/hover-card.astro index 13c668111..8dbec06be 100644 --- a/src/components/ui/hover-card/hover-card.astro +++ b/src/components/ui/hover-card/hover-card.astro @@ -66,15 +66,12 @@ const { diff --git a/src/components/ui/navigation-menu/navigation-menu.astro b/src/components/ui/navigation-menu/navigation-menu.astro index 8ae070062..21d6fdeff 100644 --- a/src/components/ui/navigation-menu/navigation-menu.astro +++ b/src/components/ui/navigation-menu/navigation-menu.astro @@ -60,8 +60,9 @@ const { diff --git a/src/components/ui/popover/popover.astro b/src/components/ui/popover/popover.astro index 4d93571c6..cc59e215c 100644 --- a/src/components/ui/popover/popover.astro +++ b/src/components/ui/popover/popover.astro @@ -53,8 +53,9 @@ const { diff --git a/src/components/ui/radio-group/radio-group.astro b/src/components/ui/radio-group/radio-group.astro index a9d8646b0..e8faa86d3 100644 --- a/src/components/ui/radio-group/radio-group.astro +++ b/src/components/ui/radio-group/radio-group.astro @@ -36,8 +36,9 @@ const { diff --git a/src/components/ui/select/select.astro b/src/components/ui/select/select.astro index df87b21e1..f72729651 100644 --- a/src/components/ui/select/select.astro +++ b/src/components/ui/select/select.astro @@ -73,13 +73,9 @@ const { diff --git a/src/components/ui/sheet/sheet.astro b/src/components/ui/sheet/sheet.astro index 28643107b..cf0e3378d 100644 --- a/src/components/ui/sheet/sheet.astro +++ b/src/components/ui/sheet/sheet.astro @@ -31,8 +31,9 @@ const { diff --git a/src/components/ui/slider/slider.astro b/src/components/ui/slider/slider.astro index cfcfb6adf..ef5013be8 100644 --- a/src/components/ui/slider/slider.astro +++ b/src/components/ui/slider/slider.astro @@ -80,8 +80,9 @@ 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..b2554863b 100644 --- a/src/components/ui/switch/switch.astro +++ b/src/components/ui/switch/switch.astro @@ -67,8 +67,9 @@ const switchSizeStyle = { diff --git a/src/components/ui/tabs/tabs.astro b/src/components/ui/tabs/tabs.astro index 5a5605a9b..11c4a126d 100644 --- a/src/components/ui/tabs/tabs.astro +++ b/src/components/ui/tabs/tabs.astro @@ -32,8 +32,9 @@ const { diff --git a/src/components/ui/toggle/toggle.astro b/src/components/ui/toggle/toggle.astro index 2f5a420d3..820f0d4b1 100644 --- a/src/components/ui/toggle/toggle.astro +++ b/src/components/ui/toggle/toggle.astro @@ -36,8 +36,9 @@ const { diff --git a/src/components/ui/tooltip/tooltip.astro b/src/components/ui/tooltip/tooltip.astro index 56571d64b..f805c41d6 100644 --- a/src/components/ui/tooltip/tooltip.astro +++ b/src/components/ui/tooltip/tooltip.astro @@ -52,8 +52,9 @@ const { diff --git a/src/content/pages/components/command.mdx b/src/content/pages/components/command.mdx index ea883db52..c1ce826bb 100644 --- a/src/content/pages/components/command.mdx +++ b/src/content/pages/components/command.mdx @@ -130,6 +130,36 @@ 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 + + + +``` + ## Examples ### Basic diff --git a/src/content/pages/components/hover-card.mdx b/src/content/pages/components/hover-card.mdx index d98e21ae8..6ce52e2c3 100644 --- a/src/content/pages/components/hover-card.mdx +++ b/src/content/pages/components/hover-card.mdx @@ -159,8 +159,9 @@ the document and hidden, preserving DOM queries and nested component setup. Data Slot 1.x itself defaults to `"lazy"`, which detaches closed content. Set `mountStrategy="lazy"` on the root to opt into detaching closed content. -Initialize nested interactive components before their parent detaches them, or -keep the default eager strategy. Both modes include the content in server-rendered +Fulldev initializes nested Data Slot components inside retained content too. +Custom scripts using document queries should keep the eager strategy or wait +until the content opens. Both modes include the content in server-rendered HTML; neither adds a no-JavaScript fallback. ## API Reference diff --git a/src/content/pages/components/navigation-menu.mdx b/src/content/pages/components/navigation-menu.mdx index 29c8179b5..2d879ed8d 100644 --- a/src/content/pages/components/navigation-menu.mdx +++ b/src/content/pages/components/navigation-menu.mdx @@ -194,8 +194,9 @@ the document and hidden, preserving DOM queries and nested component setup. Data Slot 1.x itself defaults to `"lazy"`, which detaches closed content. Set `mountStrategy="lazy"` on the root to opt into detaching closed content. -Initialize nested interactive components before their parent detaches them, or -keep the default eager strategy. Both modes include the content in server-rendered +Fulldev initializes nested Data Slot components inside retained content too. +Custom scripts using document queries should keep the eager strategy or wait +until the content opens. Both modes include the content in server-rendered HTML; neither adds a no-JavaScript fallback. ## API Reference diff --git a/src/content/pages/components/select.mdx b/src/content/pages/components/select.mdx index d00728f2c..ccbe8116d 100644 --- a/src/content/pages/components/select.mdx +++ b/src/content/pages/components/select.mdx @@ -278,8 +278,9 @@ the document and hidden, preserving DOM queries and nested component setup. Data Slot 1.x itself defaults to `"lazy"`, which detaches closed content. Set `mountStrategy="lazy"` on the root to opt into detaching closed content. -Initialize nested interactive components before their parent detaches them, or -keep the default eager strategy. Both modes include the content in server-rendered +Fulldev initializes nested Data Slot components inside retained content too. +Custom scripts using document queries should keep the eager strategy or wait +until the content opens. Both modes include the content in server-rendered HTML; neither adds a no-JavaScript fallback. ## API Reference diff --git a/src/content/pages/components/tooltip.mdx b/src/content/pages/components/tooltip.mdx index 2a4207658..d1a5ee2c7 100644 --- a/src/content/pages/components/tooltip.mdx +++ b/src/content/pages/components/tooltip.mdx @@ -107,8 +107,9 @@ the document and hidden, preserving DOM queries and nested component setup. Data Slot 1.x itself defaults to `"lazy"`, which detaches closed content. Set `mountStrategy="lazy"` on the root to opt into detaching closed content. -Initialize nested interactive components before their parent detaches them, or -keep the default eager strategy. Both modes include the content in server-rendered +Fulldev initializes nested Data Slot components inside retained content too. +Custom scripts using document queries should keep the eager strategy or wait +until the content opens. Both modes include the content in server-rendered HTML; neither adds a no-JavaScript fallback. ## API Reference diff --git a/src/content/pages/docs/installation.mdx b/src/content/pages/docs/installation.mdx index bbb9a8363..cf1637db7 100644 --- a/src/content/pages/docs/installation.mdx +++ b/src/content/pages/docs/installation.mdx @@ -130,3 +130,23 @@ 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, including the shared `src/lib/data-slot.ts` helper. + +The helper initializes new roots on `astro:page-load` and destroys outgoing +controllers on `astro:before-swap`. This releases modal stacks, portals, listeners +and scroll locks before Astro's `ClientRouter` replaces the page. Roots within a +matching `transition:persist` boundary retain their controllers. + +Select, Tooltip, Hover Card and Navigation Menu keep closed content mounted by +default. Use their `mountStrategy="lazy"` prop to opt into Data Slot's detached +content behavior. See each component's content mounting notes before changing +custom scripts that query closed content. + +`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). diff --git a/src/lib/data-slot.ts b/src/lib/data-slot.ts new file mode 100644 index 000000000..57ef30f49 --- /dev/null +++ b/src/lib/data-slot.ts @@ -0,0 +1,41 @@ +import { getRoots, hasRootBinding } from "@data-slot/core" + +type Controller = { destroy(): void } + +/** Bind new roots once and release outgoing controllers before Astro swaps pages. */ +export function initializeDataSlot( + slot: string, + create: (root: HTMLElement) => Controller | undefined +) { + const controllers = new Map() + + const initialize = () => { + for (const root of getRoots(document, slot)) { + if (hasRootBinding(root, `@data-slot/${slot}`)) continue + const controller = create(root) + if (controller) controllers.set(root, controller) + } + } + + initialize() + document.addEventListener("astro:page-load", initialize) + document.addEventListener("astro:before-swap", (event) => { + const nextDocument = (event as Event & { newDocument: Document }) + .newDocument + const persisted = new Set( + Array.from( + nextDocument.querySelectorAll("[data-astro-transition-persist]") + ).map((element) => element.getAttribute("data-astro-transition-persist")) + ) + for (const [root, controller] of controllers) { + const persist = root.closest("[data-astro-transition-persist]") + if ( + persist && + persisted.has(persist.getAttribute("data-astro-transition-persist")) + ) + continue + controller.destroy() + controllers.delete(root) + } + }) +} diff --git a/tests/data-slot-consumer.spec.ts b/tests/data-slot-consumer.spec.ts new file mode 100644 index 000000000..5082bc36f --- /dev/null +++ b/tests/data-slot-consumer.spec.ts @@ -0,0 +1,185 @@ +import { expect, test } from "@playwright/test" + +test.use({ baseURL: "http://127.0.0.1:4176" }) + +test.beforeEach(async ({ page }) => { + page.on("pageerror", (error) => { + throw error + }) + await page.goto("/") + await expect( + page.getByRole("button", { name: "Consumer dialog", exact: true }) + ).toHaveAttribute("aria-expanded", "false") +}) + +test("consumer: live Astro swaps release modal stack and scroll lock", async ({ + page, +}) => { + // Survives client navigation, but would be lost on a full page load. + await page.evaluate(() => { + ;(window as Window & { navigationProbe?: boolean }).navigationProbe = true + }) + for (let i = 0; i < 3; i++) { + await page.getByRole("button", { name: "Initialize again" }).click() + const trigger = page.getByRole("button", { + name: "Consumer dialog", + exact: true, + }) + await trigger.click() + const content = page.getByRole("dialog", { + name: "Consumer dialog", + exact: true, + }) + await expect(content).toHaveAttribute("data-stack-index", "0") + await expect + .poll(() => page.evaluate(() => document.documentElement.style.overflow)) + .toBe("hidden") + await content.getByRole("link", { name: "Navigate while open" }).click() + await expect(page).toHaveURL(i % 2 === 0 ? /\/next\/$/ : /:4176\/$/) + await expect(content).toBeHidden() + await expect + .poll(() => page.evaluate(() => document.documentElement.style.overflow)) + .toBe("") + await expect + .poll(() => + page.evaluate( + () => + (window as Window & { navigationProbe?: boolean }).navigationProbe + ) + ) + .toBe(true) + } +}) + +test("consumer: nested Select Escape leaves its parent dialog open", async ({ + page, +}) => { + await page + .getByRole("button", { name: "Consumer dialog", exact: true }) + .press("Enter") + const dialog = page.getByRole("dialog", { + name: "Consumer dialog", + exact: true, + }) + await expect( + dialog.getByRole("button", { name: "Close", exact: true }) + ).toBeFocused() + await dialog.getByRole("combobox").press("ArrowDown") + await expect( + page.getByRole("option", { name: "One", exact: true }) + ).toBeVisible() + await page.keyboard.press("Escape") + await expect( + page.locator('[data-slot="select-content"]:visible') + ).toHaveCount(0) + await expect(dialog).toBeVisible() + await expect(dialog.getByRole("combobox")).toBeFocused() + await page.keyboard.press("Escape") + await expect(dialog).toBeHidden() +}) + +test("consumer: CommandItem href navigates from the keyboard", async ({ + page, +}) => { + for (let i = 0; i < 3; i++) + await page.getByRole("button", { name: "Initialize again" }).click() + const input = page.getByPlaceholder("Navigate by command") + await input.fill("next") + await input.press("ArrowDown") + await input.press("Enter") + await expect(page).toHaveURL(/\/next\/$/) +}) + +test("consumer: lazy retained roots initialize nested Combobox and Hover Card", async ({ + page, + browserName, +}) => { + for (let i = 0; i < 3; i++) + await page.getByRole("button", { name: "Initialize again" }).click() + await expect( + page.locator('[data-slot="navigation-menu-content"]') + ).toHaveCount(0) + await page + .getByRole("button", { name: "Lazy nested controls" }) + .press("Enter") + const input = page.getByPlaceholder("Nested framework") + await input.fill("Astro") + await input.press("ArrowDown") + await input.press("Enter") + await expect(input).toHaveValue("Astro") + // The combobox toggle is excluded from the tab order. + const tab = browserName === "webkit" ? "Alt+Tab" : "Tab" + await page.keyboard.press(tab) + await expect( + page.getByRole("button", { name: "Nested preview" }) + ).toBeFocused() + await expect( + page.getByText("Retained hover card", { exact: true }) + ).toBeVisible() + await page.keyboard.press("Escape") + await expect( + page.getByText("Retained hover card", { exact: true }) + ).toHaveCount(0) + await expect( + page.locator('[data-slot="navigation-menu-content"]') + ).toBeVisible() + await page.keyboard.press("Escape") + await expect( + page.locator('[data-slot="navigation-menu-content"]') + ).toHaveCount(0) +}) + +test("consumer: native required validation, submit, reset and persistent control", async ({ + page, +}) => { + const form = page.locator("#choices") + await form.getByRole("button", { name: "Submit choices" }).click() + await expect(form.getByRole("combobox")).toBeFocused() + await expect(page.locator("#result")).toBeEmpty() + await form.getByRole("combobox").press("ArrowDown") + await page.getByRole("option", { name: "Banana", exact: true }).click() + await expect(form.getByRole("combobox")).toContainText("Banana") + await form.getByRole("button", { name: "Submit choices" }).click() + await expect(page.locator("#result")).toContainText('"fruit":"banana"') + await form.getByRole("button", { name: "Reset choices" }).click() + await expect(form.getByRole("combobox")).toContainText("Required fruit") + await expect(form.getByRole("switch", { name: "Updates" })).toBeChecked() + await page.getByRole("switch", { name: "Persisted preference" }).click() + await page.getByRole("link", { name: "Navigate", exact: true }).click() + await expect(page).toHaveURL(/\/next\/$/) + await expect( + page.getByRole("switch", { name: "Persisted preference" }) + ).toBeChecked() + await page + .getByRole("switch", { name: "Persisted preference" }) + .press("Space") + await expect( + page.getByRole("switch", { name: "Persisted preference" }) + ).not.toBeChecked() +}) + +test("consumer: lazy Tooltip and controlled Hover Card keep their mounting contracts", async ({ + page, + browserName, +}) => { + const tooltip = page.getByRole("button", { + name: "Lazy tooltip", + exact: true, + }) + const message = page.getByText("Retained tooltip", { exact: true }) + await expect(message).toHaveCount(0) + await tooltip.focus() + await expect(message).toBeVisible() + await page.evaluate(() => + document.dispatchEvent(new Event("astro:page-load")) + ) + await page.keyboard.press("Escape") + await expect(message).toHaveCount(0) + await page.keyboard.press(browserName === "webkit" ? "Alt+Tab" : "Tab") + await expect( + page.getByRole("button", { name: "Controlled preview" }) + ).toBeFocused() + await expect( + page.getByText("Controlled content", { exact: true }) + ).toBeHidden() +}) diff --git a/tests/data-slot.spec.ts b/tests/data-slot.spec.ts new file mode 100644 index 000000000..989478eab --- /dev/null +++ b/tests/data-slot.spec.ts @@ -0,0 +1,344 @@ +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: eager 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(5) + 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: eager 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(2) + 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}: eager 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(1) + 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 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 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 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/fixtures/data-slot-consumer.astro b/tests/fixtures/data-slot-consumer.astro new file mode 100644 index 000000000..9a7e67b26 --- /dev/null +++ b/tests/fixtures/data-slot-consumer.astro @@ -0,0 +1,166 @@ +--- +import { ClientRouter } from "astro:transitions" + +import { + Combobox, + ComboboxContent, + ComboboxInput, + ComboboxItem, + ComboboxList, +} from "@/components/ui/combobox" +import { + Command, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command" +import { + Dialog, + DialogContent, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { + HoverCard, + HoverCardContent, + HoverCardTrigger, +} from "@/components/ui/hover-card" +import { + NavigationMenu, + NavigationMenuContent, + NavigationMenuItem, + NavigationMenuList, + NavigationMenuTrigger, +} from "@/components/ui/navigation-menu" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { Switch } from "@/components/ui/switch" +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip" + +import "@/styles/global.css" + +const next = Astro.url.pathname === "/" ? "/next/" : "/" +--- + + + + + Data Slot consumer + + +

Data Slot consumer

+ Navigate + +

0

+ + + Next consumer page + + + Consumer dialog + + Consumer dialog + Navigate while open + + + + + + Lazy nested controls + + + + AstroVue + + + Nested preview + Retained hover card + + + + + + Lazy tooltipRetained tooltip + + + Controlled previewControlled content + +
+ +
+
+ + + + + + + + From 707af730cd6ed170b92b7de1c6c3de471efcb9d1 Mon Sep 17 00:00:00 2001 From: Sil Date: Sat, 26 Sep 2026 17:08:00 +0200 Subject: [PATCH 3/9] Preserve command palette initial input focus with Data Slot 1.x --- public/r/command.json | 2 +- src/components/ui/command/command.astro | 10 +++++++++- tests/data-slot.spec.ts | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/public/r/command.json b/public/r/command.json index d7069fbac..c93568429 100644 --- a/public/r/command.json +++ b/public/r/command.json @@ -14,7 +14,7 @@ "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" }, { diff --git a/src/components/ui/command/command.astro b/src/components/ui/command/command.astro index 76cf86e83..dcf45bbb9 100644 --- a/src/components/ui/command/command.astro +++ b/src/components/ui/command/command.astro @@ -46,12 +46,19 @@ const { \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 \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/combobox.json b/public/r/combobox.json index 5921723d8..a5079406d 100644 --- a/public/r/combobox.json +++ b/public/r/combobox.json @@ -15,12 +15,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 \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 \n
\n \n\n", "type": "registry:ui" }, { diff --git a/public/r/command.json b/public/r/command.json index c93568429..71205b4a3 100644 --- a/public/r/command.json +++ b/public/r/command.json @@ -14,7 +14,7 @@ "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" }, { diff --git a/public/r/data-slot.json b/public/r/data-slot.json index a7bfee53f..3c67a2c9c 100644 --- a/public/r/data-slot.json +++ b/public/r/data-slot.json @@ -9,7 +9,7 @@ "files": [ { "path": "src/lib/data-slot.ts", - "content": "import { getRoots, hasRootBinding } from \"@data-slot/core\"\n\ntype Controller = { destroy(): void }\n\n/** Bind new roots once and release outgoing controllers before Astro swaps pages. */\nexport function initializeDataSlot(\n slot: string,\n create: (root: HTMLElement) => Controller | undefined\n) {\n const controllers = new Map()\n\n const initialize = () => {\n for (const root of getRoots(document, slot)) {\n if (hasRootBinding(root, `@data-slot/${slot}`)) continue\n const controller = create(root)\n if (controller) controllers.set(root, controller)\n }\n }\n\n initialize()\n document.addEventListener(\"astro:page-load\", initialize)\n document.addEventListener(\"astro:before-swap\", (event) => {\n const nextDocument = (event as Event & { newDocument: Document })\n .newDocument\n const persisted = new Set(\n Array.from(\n nextDocument.querySelectorAll(\"[data-astro-transition-persist]\")\n ).map((element) => element.getAttribute(\"data-astro-transition-persist\"))\n )\n for (const [root, controller] of controllers) {\n const persist = root.closest(\"[data-astro-transition-persist]\")\n if (\n persist &&\n persisted.has(persist.getAttribute(\"data-astro-transition-persist\"))\n )\n continue\n controller.destroy()\n controllers.delete(root)\n }\n })\n}\n", + "content": "import { containsWithPortals, getRoots, hasRootBinding } from \"@data-slot/core\"\n\ntype Controller = { destroy(): void; close?(): void; hide?(): void }\nconst controllers = new Map()\n\ndocument.addEventListener(\"astro:before-swap\", (event) => {\n const transition = event as Event & {\n newDocument: Document\n swap(): void\n }\n const selector = \"[data-astro-transition-persist]\"\n const nextNames = new Set(\n Array.from(transition.newDocument.querySelectorAll(selector)).map(\n (element) => element.getAttribute(\"data-astro-transition-persist\")\n )\n )\n const boundaries = Array.from(document.querySelectorAll(selector)).filter(\n (element) =>\n nextNames.has(element.getAttribute(\"data-astro-transition-persist\"))\n )\n // Astro carries authored boundaries, but body portals live outside them.\n const portals = Array.from(document.body.children).filter((element) =>\n boundaries.some(\n (boundary) =>\n !boundary.contains(element) && containsWithPortals(boundary, element)\n )\n )\n const retained = new Set()\n const slots = new Set(\n Array.from(controllers.keys()).map((root) =>\n root.getAttribute(\"data-slot\")!\n )\n )\n for (const scope of [...boundaries, ...portals]) {\n retained.add(scope)\n for (const slot of slots) {\n for (const root of getRoots(scope, slot)) retained.add(root)\n }\n }\n for (const [root, controller] of controllers) {\n if (retained.has(root)) {\n // Reopening creates modal isolation and scroll locks for the new body.\n controller.close?.()\n controller.hide?.()\n continue\n }\n controller.destroy()\n controllers.delete(root)\n }\n if (portals.length) {\n const swap = transition.swap\n transition.swap = () => {\n swap()\n document.body.append(...portals)\n }\n }\n})\n\n/** Bind new roots once and release outgoing controllers before Astro swaps pages. */\nexport function initializeDataSlot(\n slot: string,\n create: (root: HTMLElement) => Controller\n) {\n const initialize = () => {\n for (const root of getRoots(document, slot)) {\n if (hasRootBinding(root, `@data-slot/${slot}`)) continue\n controllers.set(root, create(root))\n }\n }\n\n initialize()\n document.addEventListener(\"astro:page-load\", initialize)\n}\n", "type": "registry:lib" } ], 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 showCopyButton && (\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 }\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 \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 }\n\n\n\n", "type": "registry:block" } ], diff --git a/public/r/dropdown-menu.json b/public/r/dropdown-menu.json index da3be9bb0..5d4f6d640 100644 --- a/public/r/dropdown-menu.json +++ b/public/r/dropdown-menu.json @@ -23,12 +23,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 \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 \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 55181e5a9..7db59886f 100644 --- a/public/r/hover-card.json +++ b/public/r/hover-card.json @@ -13,12 +13,12 @@ "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 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 = \"eager\",\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 \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 \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/navigation-menu.json b/public/r/navigation-menu.json index b265ca335..a6f17fd0b 100644 --- a/public/r/navigation-menu.json +++ b/public/r/navigation-menu.json @@ -13,7 +13,7 @@ "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 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 = \"eager\",\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" }, { @@ -53,7 +53,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 \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 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 \n \n \n
\n \n \n\n", "type": "registry:ui" }, { diff --git a/public/r/popover.json b/public/r/popover.json index fb6b0cef8..ad470a44c 100644 --- a/public/r/popover.json +++ b/public/r/popover.json @@ -12,7 +12,7 @@ "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" }, { @@ -22,7 +22,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 \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 \n
\n \n\n", "type": "registry:ui" }, { diff --git a/public/r/registry.json b/public/r/registry.json index 88ef7fc55..322a6637d 100644 --- a/public/r/registry.json +++ b/public/r/registry.json @@ -205,10 +205,6 @@ "dependencies": [ "@lucide/astro" ], - "registryDependencies": [ - "@fulldev/button", - "@fulldev/dropdown-menu" - ], "files": [ { "path": "src/components/ui/banner/banner.astro", @@ -894,7 +890,6 @@ "docs": "https://ui.full.dev/components/input-group/", "registryDependencies": [ "@fulldev/button", - "@fulldev/dropdown-menu", "@fulldev/input", "@fulldev/textarea" ], diff --git a/public/r/select.json b/public/r/select.json index dc41e829f..d8dff2347 100644 --- a/public/r/select.json +++ b/public/r/select.json @@ -13,7 +13,7 @@ "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 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 = \"eager\",\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" }, { @@ -28,7 +28,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 \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 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 \n
\n \n \n\n", "type": "registry:ui" }, { diff --git a/public/r/sidebar-1.json b/public/r/sidebar-1.json index 82b75394e..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 { 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 {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", + "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/slider.json b/public/r/slider.json index 02d86195d..d79b7bc9b 100644 --- a/public/r/slider.json +++ b/public/r/slider.json @@ -12,7 +12,7 @@ "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 \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 \n \n {\n Array.from({ length: thumbCount }).map(() => (\n \n ))\n }\n \n\n\n\n", "type": "registry:ui" }, { diff --git a/public/r/tabs.json b/public/r/tabs.json index d61bf01da..715a5bf0b 100644 --- a/public/r/tabs.json +++ b/public/r/tabs.json @@ -17,7 +17,7 @@ }, { "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