diff --git a/.changeset/react-registry.md b/.changeset/react-registry.md new file mode 100644 index 000000000..e30ada0a9 --- /dev/null +++ b/.changeset/react-registry.md @@ -0,0 +1,11 @@ +--- +"fulldev-ui": minor +--- + +Add Fulldev UI for React: every shadcn/ui Base UI component, the Fulldev components and all 82 blocks as React components, in every shadcn/ui style. Install them with the shadcn CLI from the React registry, `https://ui.full.dev/r/react/styles/{style}/{name}.json`, starting with `npx shadcn@latest init https://ui.full.dev/r/react/styles/base-vega/base.json`. The npm package does not include the React registry. + +Add the examples from the shadcn/ui documentation as `@fulldev/-examples` items: the official React source in the React registry, native ports in the Astro registry for the components Fulldev UI has in Astro. + +The docs now have an Astro and a React edition at `/astro/` and `/react/`; the former `/docs/`, `/components/` and `/blocks/` addresses redirect to the Astro edition. `Sidebar1` takes optional header content below its logo (a `header` slot in Astro, a `header` prop in React). + +The Astro `SidebarProvider` now leaves a sidebar nested inside another provider alone: the outer one no longer updates its trigger, rail and tooltips, the nested one keeps its state out of the shared `sidebar_state` cookie, and a provider whose inline script did not run initializes on `astro:page-load`. diff --git a/README.md b/README.md index 414d9f692..5d40c5baf 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ A shadcn-compatible set of components built for [Astro][astro], designed for con - **100+ Components & Blocks** — Ready-to-use UI components and pre-built page blocks - **Tailwind CSS v4** — Styled with the latest Tailwind CSS - **TypeScript** — Full TypeScript support +- **React**: the same components and blocks for React; see [react/README.md](react/README.md) ## Installation diff --git a/astro.config.ts b/astro.config.ts index 0d9dfd48b..0bd78eeea 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -1,3 +1,4 @@ +import { readdirSync } from "node:fs" import { defineConfig, fontProviders } from "astro/config" import { unified } from "@astrojs/markdown-remark" import mdx from "@astrojs/mdx" @@ -5,7 +6,40 @@ import liveCode from "astro-live-code" import fulldevIntegration from "./src/lib/integration" +// The docs used to live at /docs/, /components/ and /blocks/; they are the +// Astro edition now. Netlify answers these with a 301 (netlify.toml). +// Docs tables scroll inside the content column instead of widening the page. +type Node = { type: string; tagName?: string; children?: Node[] } +const scrollTables = () => (tree: Node) => { + const wrap = (node: Node) => { + node.children = node.children?.map((child) => { + if (child.type === "element" && child.tagName === "table") + return { + type: "element", + tagName: "div", + properties: { className: ["typeset-scroll"] }, + children: [child], + } as Node + wrap(child) + return child + }) + } + wrap(tree) +} + +const legacyRedirects = Object.fromEntries( + readdirSync("src/content/pages/astro", { recursive: true }) + .map((file) => String(file).replace(/(\/?index)?\.mdx$/, "")) + .filter((path) => /^(docs|components|blocks)/.test(path)) + .map((path) => [`/${path}/`, `/astro/${path}/`]) +) + +// React previews come from the gallery in react/, at /preview/react/. In +// development its Vite server runs on REACT_PREVIEW_PORT (pnpm dev:react). +const reactPreviewPort = process.env.REACT_PREVIEW_PORT ?? "4322" + export default defineConfig({ + redirects: legacyRedirects, server: { host: "127.0.0.1", port: 4321, @@ -13,6 +47,17 @@ export default defineConfig({ vite: { server: { allowedHosts: ["otis.tailb5cb80.ts.net"], + proxy: { + "/preview/react/": { + target: `http://127.0.0.1:${reactPreviewPort}`, + ws: true, + }, + }, + }, + // Vite's preview server would inherit the proxy; astro preview serves the + // built galleries from dist/preview/react/ instead. + preview: { + proxy: {}, }, // The docs create page imports this; prebundle it so the first dev visit // does not trigger a dependency re-optimization. @@ -35,7 +80,7 @@ export default defineConfig({ markdown: { // astro-live-code adds a remark plugin, which only runs on the unified // processor. Astro 7 defaults to Sätteri. - processor: unified(), + processor: unified({ rehypePlugins: [scrollTables] }), shikiConfig: { themes: { light: "github-light-high-contrast", diff --git a/eslint.config.js b/eslint.config.js index 02458847a..27b3c1a45 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,6 @@ import js from "@eslint/js" import astro from "eslint-plugin-astro" +import reactHooks from "eslint-plugin-react-hooks" import { defineConfig, globalIgnores } from "eslint/config" import globals from "globals" import tseslint from "typescript-eslint" @@ -11,12 +12,62 @@ export default defineConfig([ extends: [js.configs.recommended, tseslint.configs.recommended], languageOptions: { globals: { ...globals.browser, ...globals.node } }, }, + { + // The React port, with the same rules as the shadcn/ui React templates. + files: ["react/**/*.{ts,tsx}"], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs.flat.recommended, + ], + languageOptions: { globals: globals.browser }, + }, + { + // Official shadcn/ui source, kept as the CLI installs it. + files: [ + "react/src/components/ui/carousel.tsx", + "react/src/hooks/use-mobile.ts", + ], + rules: { "react-hooks/set-state-in-effect": "off" }, + }, + { + // The official shadcn/ui docs examples and the docs helpers they import, + // unchanged. + files: [ + "react/src/components/examples/**/*.tsx", + "react/src/components/language-selector.tsx", + "react/src/components/markdown.tsx", + "react/src/components/message-animated.tsx", + "react/src/lib/ai.ts", + "react/src/lib/message-animations.ts", + "react/src/hooks/use-copy-to-clipboard.ts", + "react/src/hooks/use-media-query.tsx", + ], + rules: { + "@typescript-eslint/no-unused-expressions": "off", + "@typescript-eslint/no-unused-vars": "off", + "no-useless-assignment": "off", + "react-hooks/refs": "off", + "react-hooks/set-state-in-effect": "off", + }, + }, ...astro.configs.recommended, ...astro.configs["jsx-a11y-recommended"], + { + // Ports of the official shadcn/ui examples keep their content, such as + // alt="Photo" and href="#". + files: ["src/components/examples/**/*.astro"], + rules: { + "astro/jsx-a11y/anchor-is-valid": "off", + "astro/jsx-a11y/img-redundant-alt": "off", + }, + }, { // A site installs whole components, so tools such as knip can only tell // which ones it uses when components import each other through index.ts. - files: ["**/*.{js,mjs,ts,astro}"], + files: ["**/*.{js,mjs,ts,tsx,astro}"], + // The React gallery and its build read from the repository. + ignores: ["react/gallery/**", "react/vite.config.ts"], rules: { "no-restricted-imports": [ "error", diff --git a/html-validate.config.mjs b/html-validate.config.mjs index 11c4d0e47..58cd0a6de 100644 --- a/html-validate.config.mjs +++ b/html-validate.config.mjs @@ -16,14 +16,30 @@ export default defineFlatConfig([ // the page's own breadcrumb or table of contents, so the landmark names // repeat. A site renders each of these landmarks once. files: [ - "dist/blocks/banner/index.html", - "dist/blocks/footer/index.html", - "dist/blocks/header/index.html", - "dist/components/banner/index.html", - "dist/components/breadcrumb/index.html", - "dist/components/pagination/index.html", - "dist/components/toc/index.html", + "dist/astro/blocks/banner/index.html", + "dist/astro/blocks/footer/index.html", + "dist/astro/blocks/header/index.html", + "dist/astro/components/banner/index.html", + "dist/astro/components/breadcrumb/index.html", + "dist/astro/components/navigation-menu/index.html", + "dist/astro/components/pagination/index.html", + "dist/astro/components/sidebar/index.html", + "dist/astro/components/toc/index.html", ], rules: { "unique-landmark": "off" }, }, + { + // The official sidebar example is a full app layout: its SidebarInset is + // the app's main element, rendered here inside the docs page's own main. + files: ["dist/astro/components/sidebar/index.html"], + rules: { "no-multiple-main": "off", "element-permitted-content": "off" }, + }, + { + // ItemGroup and Item follow shadcn/ui: ARIA list roles on div and a, so + // an item can be a link. + files: ["dist/astro/components/item/index.html"], + rules: { + "prefer-native-element": ["error", { exclude: ["list", "listitem"] }], + }, + }, ]) diff --git a/knip.jsonc b/knip.jsonc index 2f75b8448..0edb576c5 100644 --- a/knip.jsonc +++ b/knip.jsonc @@ -1,27 +1,52 @@ { "$schema": "https://unpkg.com/knip@6/schema.json", - "entry": [ - // The registry publishes these; sites import a component through its index. - "src/components/ui/*/index.ts", - "src/components/blocks/*.astro", - "src/lib/utils.ts", - // The page route loads layouts through import.meta.glob. - "src/layouts/*.astro", - // Docs pages, loaded by the content collection, import the examples. - "src/content/**/*.mdx", - // astro.config.ts passes this to astro-live-code by path. - "src/components/live-code.astro", - // Read by the html-validate CLI in the build. - "html-validate.config.mjs", - ], - // Read as text by src/lib/styles.ts and the registry scripts. - "ignoreFiles": ["registry/styles/**/*.css"], - "ignoreIssues": { - // Part of the installed price component, shipped unchanged. - "src/components/ui/price/format-price-value.ts": ["exports"], + "workspaces": { + ".": { + "entry": [ + // The registry publishes these; sites import a component through its index. + "src/components/ui/*/index.ts", + "src/components/blocks/*.astro", + "src/lib/utils.ts", + // The page route loads layouts through import.meta.glob. + "src/layouts/*.astro", + // Example files install from the registry; the docs load them through + // import.meta.glob. + "src/components/examples/*/*.astro", + // Docs pages, loaded by the content collection, import the examples. + "src/content/**/*.mdx", + // astro.config.ts passes this to astro-live-code by path. + "src/components/live-code.astro", + // Read by the html-validate CLI in the build. + "html-validate.config.mjs", + ], + // Read as text by src/lib/styles.ts and the registry scripts. + "ignoreFiles": ["registry/styles/**/*.css"], + "ignoreIssues": { + // Part of the installed price component, shipped unchanged. + "src/components/ui/price/format-price-value.ts": ["exports"], + }, + "ignoreDependencies": [ + // Read from node_modules by the Icon component. + "lucide-static", + ], + }, + "react": { + "entry": [ + // The React registry publishes these as installable files. + "src/components/ui/*.tsx", + "src/components/blocks/*.tsx", + "src/components/examples/*/*.tsx", + "src/hooks/*.{ts,tsx}", + "src/lib/*.ts", + // The gallery loads its demos through import.meta.glob. + "gallery/ui/*.tsx", + "gallery/blocks/*.tsx", + ], + "ignoreIssues": { + // shadcn/ui docs helpers that example items install, shipped unchanged. + "src/components/language-selector.tsx": ["exports", "types"], + "src/components/message-animated.tsx": ["types"], + }, + }, }, - "ignoreDependencies": [ - // Read from node_modules by the Icon component. - "lucide-static", - ], } diff --git a/linkinator.config.json b/linkinator.config.json index 43e2af2ec..96f1c7ee8 100644 --- a/linkinator.config.json +++ b/linkinator.config.json @@ -2,5 +2,7 @@ "recurse": true, "checkFragments": true, "skip": ["^https?://(?!127\\.0\\.0\\.1[:/])"], - "verbosity": "error" + "skipFragment": ["^/"], + "verbosity": "error", + "retryErrors": true } diff --git a/netlify.toml b/netlify.toml index b2e97906f..bf3b4e633 100644 --- a/netlify.toml +++ b/netlify.toml @@ -30,3 +30,23 @@ to = "https://eu.i.posthog.com/:splat" host = "eu.i.posthog.com" status = 200 force = true + +# The docs moved to the Astro edition; the React gallery became the React +# edition, with its previews at /preview/react/. +[[redirects]] +from = "/docs/*" +to = "/astro/docs/:splat" +status = 301 +force = true + +[[redirects]] +from = "/components/*" +to = "/astro/components/:splat" +status = 301 +force = true + +[[redirects]] +from = "/blocks/*" +to = "/astro/blocks/:splat" +status = 301 +force = true diff --git a/package.json b/package.json index b9fc0f874..227d1388e 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,9 @@ "README.md", "registry.json", "public/r", + "!public/r/react", "src/components/blocks", + "src/components/examples", "src/components/ui", "src/lib/utils.ts", "src/styles/global.css" @@ -55,17 +57,17 @@ "dev": "pnpm stop && astro dev --host 127.0.0.1 --port 4321", "stop": "lsof -tiTCP:4321 -sTCP:LISTEN | xargs kill 2>/dev/null || true", "preview": "pnpm stop && pnpm build && astro preview --host 127.0.0.1 --port 4321", - "typecheck": "tsc --noEmit --noCheck && astro check --minimumFailingSeverity hint", + "typecheck": "tsc --noEmit --noCheck && astro check --minimumFailingSeverity hint && tsc --noEmit -p react", "check": "prettier --check . && pnpm typecheck && eslint . && knip && node scripts/images.ts --check && pnpm registry:check && pnpm test", "test": "node --test tests/*.test.mjs", "fix": "prettier --write . && eslint . --fix", "images": "node scripts/images.ts", "ui:add": "node scripts/ui-add.ts", - "build": "astro build && html-validate dist && linkinator dist", + "build": "astro build && pnpm --dir react build && html-validate dist && linkinator dist", "a11y": "pnpm build && playwright install chromium --only-shell && node scripts/a11y.mjs", - "registry:build": "pnpm registry:meta && node scripts/registry-adapt.mjs && shadcn build --output node_modules/.cache/fulldev-registry && node scripts/registry-styles.mjs && prettier --write registry.json public/r registry/styles/adapted --log-level warn", - "registry:check": "pnpm registry:validate && pnpm registry:build && git diff --exit-code -- registry.json public/r registry/styles/adapted", - "registry:validate": "node scripts/registry-validate.mjs", + "registry:build": "pnpm registry:meta && node scripts/registry-adapt.mjs && shadcn build --output node_modules/.cache/fulldev-registry && node scripts/registry-styles.mjs && shadcn build -c react -o ../node_modules/.cache/fulldev-registry-react && node scripts/registry-styles.mjs node_modules/.cache/fulldev-registry-react react/registry.json public/r/react && prettier --write registry.json react/registry.json public/r registry/styles/adapted --log-level warn", + "registry:check": "pnpm registry:validate && pnpm registry:build && git diff --exit-code -- registry.json react/registry.json public/r registry/styles/adapted", + "registry:validate": "node scripts/registry-validate.mjs && cd react && node ../scripts/registry-validate.mjs", "release": "changeset version && pnpm install --lockfile-only", "release:publish": "pnpm registry:check && changeset publish", "registry:meta": "node scripts/registry-meta.mjs" @@ -127,6 +129,7 @@ "eslint": "^10.11.0", "eslint-plugin-astro": "^3.2.1", "eslint-plugin-jsx-a11y": "^6.10.2", + "eslint-plugin-react-hooks": "^7.1.1", "globals": "^17.13.0", "html-validate": "^11.16.1", "knip": "^6.39.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 79954b676..76e24f712 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -320,6 +320,9 @@ importers: eslint-plugin-jsx-a11y: specifier: ^6.10.2 version: 6.10.2(eslint@10.11.0(jiti@2.7.0)) + eslint-plugin-react-hooks: + specifier: ^7.1.1 + version: 7.1.1(eslint@10.11.0(jiti@2.7.0)) globals: specifier: ^17.13.0 version: 17.13.0 @@ -337,7 +340,7 @@ importers: version: 1.64.0 posthog-js: specifier: 1.434.15 - version: 1.434.15 + version: 1.434.15(@types/react@19.3.0)(react@19.3.0) prettier: specifier: ^3.9.9 version: 3.9.9 @@ -360,8 +363,166 @@ importers: specifier: ^8.71.0 version: 8.71.0(eslint@10.11.0(jiti@2.7.0))(typescript@6.0.3) + react: + dependencies: + '@ai-sdk/react': + specifier: ^4.0.139 + version: 4.0.139(react@19.3.0)(zod@4.6.5) + '@base-ui/react': + specifier: ^1.8.0 + version: 1.8.0(@date-fns/tz@1.5.0)(@types/react@19.3.0)(date-fns@4.4.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@daypicker/persian': + specifier: 10.0.2 + version: 10.0.2(@types/react@19.3.0)(react@19.3.0) + '@fontsource-variable/vazirmatn': + specifier: ^5.3.0 + version: 5.3.0 + '@shadcn/helpers': + specifier: ^0.2.0 + version: 0.2.0(ai@7.0.136(zod@4.6.5)) + '@shadcn/react': + specifier: ^0.3.1 + version: 0.3.1(@types/react@19.3.0)(react@19.3.0) + '@streamdown/code': + specifier: ^2.0.0 + version: 2.0.0(react@19.3.0) + '@tabler/icons-react': + specifier: ^3.49.0 + version: 3.49.0(react@19.3.0) + '@tanstack/react-table': + specifier: ^9.2.8 + version: 9.2.8(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + ai: + specifier: ^7.0.136 + version: 7.0.136(zod@4.6.5) + chrono-node: + specifier: ^2.10.2 + version: 2.10.2 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + cmdk: + specifier: ^1.1.1 + version: 1.1.1(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + cn: + specifier: ^0.4.0 + version: 0.4.0 + date-fns: + specifier: ^4.4.0 + version: 4.4.0 + embla-carousel-auto-scroll: + specifier: 8.6.0 + version: 8.6.0(embla-carousel@8.6.0) + embla-carousel-autoplay: + specifier: 8.6.0 + version: 8.6.0(embla-carousel@8.6.0) + embla-carousel-react: + specifier: 8.6.0 + version: 8.6.0(react@19.3.0) + input-otp: + specifier: ^1.5.0 + version: 1.5.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + lucide-react: + specifier: ^1.53.0 + version: 1.53.0(@types/react@19.3.0)(react@19.3.0) + motion: + specifier: ^14.0.0 + version: 14.0.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + react: + specifier: ^19.3.0 + version: 19.3.0 + react-day-picker: + specifier: ^10.0.2 + version: 10.0.2(@types/react@19.3.0)(react@19.3.0) + react-dom: + specifier: ^19.3.0 + version: 19.3.0(react@19.3.0) + react-resizable-panels: + specifier: ^4.14.3 + version: 4.14.3(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + react-textarea-autosize: + specifier: ^8.5.9 + version: 8.5.9(@types/react@19.3.0)(react@19.3.0) + recharts: + specifier: 3.8.0 + version: 3.8.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react-is@19.3.0)(react@19.3.0)(redux@5.0.1) + shadcn: + specifier: ^4.21.0 + version: 4.21.1(typescript@6.0.3) + simple-icons: + specifier: ^16.33.0 + version: 16.33.0 + sonner: + specifier: ^2.0.8 + version: 2.0.8(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + streamdown: + specifier: ^2.7.0 + version: 2.7.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + tw-animate-css: + specifier: ^1.4.0 + version: 1.4.0 + zod: + specifier: ^4.6.5 + version: 4.6.5 + devDependencies: + '@tailwindcss/vite': + specifier: ^4.3.3 + version: 4.3.3(vite@8.3.2(@types/node@24.19.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1)) + '@types/node': + specifier: ^24.19.0 + version: 24.19.0 + '@types/react': + specifier: ^19.3.0 + version: 19.3.0 + '@types/react-dom': + specifier: ^19.3.0 + version: 19.3.0(@types/react@19.3.0) + '@vitejs/plugin-react': + specifier: ^6.1.2 + version: 6.1.2(vite@8.3.2(@types/node@24.19.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1)) + tailwindcss: + specifier: ^4.3.3 + version: 4.3.3 + typescript: + specifier: ~6.0.3 + version: 6.0.3 + vite: + specifier: 8.3.2 + version: 8.3.2(@types/node@24.19.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1) + packages: + '@ai-sdk/gateway@4.0.110': + resolution: {integrity: sha512-5IwnOR6v7KC+D9eddUqsCobXl/FbLUVb2LaQc/uyuQdpP3/n9s0YLc9zl4/W3IS/R2pjHrqUfCzEAeOu7bFLoQ==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/mcp@2.0.73': + resolution: {integrity: sha512-k616Rv9WSVbr6fuB5otPztkULqi66dmR+RyH8GlOvVhOqQ1of8ePuHaoO79X+UHXCOABKHtrueLUSwiv+lj6yg==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@5.0.58': + resolution: {integrity: sha512-iXSwKR/7LpHzAlyrUl+bTinwzmZ3Nmup1viwPisM5Gn5cogRdIG4rV9w1ZDuKFcrXyu/AeVs42E1CX/0aNwrfQ==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@4.0.26': + resolution: {integrity: sha512-BZ443uBEq6HuMA+Z4b7Hpm65GpZSo7pWqnYqpf/7tAO3C48JbtvAhOE2JnODFj+jodsZzfRHkAyQb64xuD2tZQ==} + engines: {node: '>=22'} + + '@ai-sdk/react@4.0.139': + resolution: {integrity: sha512-AZYw7qrn0UN1/YiUWkiQvNBMD8O8/+H9DgEDdDurr638cXSU0rthkJ38kqSSTf9x+HIpNi0Y8QUkZ5rJ1VUx/g==} + engines: {node: '>=22'} + peerDependencies: + react: ^18 || ~19.0.1 || ~19.1.2 || ^19.2.1 + '@astrojs/astro2tsx@0.1.2': resolution: {integrity: sha512-Uj/M9zbrhu5cIZEvWAGTbQJRKSxXWJ/E59BZwt7F+chrKhbfttW+9rkS/l+1QxoJP1KU3UnpM62M7yszfAI0WA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -698,6 +859,33 @@ packages: resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} + '@base-ui/react@1.8.0': + resolution: {integrity: sha512-P0/1sxo6SBVZOklKMIedvTWqw2s2IQzi9x5bIVsXu980cuSOD4NeuRSs+/L7LZQfDkZP/uRZyGPyfFl/B1oH+Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@date-fns/tz': ^1.2.0 + '@types/react': ^17 || ^18 || ^19 + date-fns: ^4.0.0 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + '@date-fns/tz': + optional: true + '@types/react': + optional: true + date-fns: + optional: true + + '@base-ui/utils@0.4.0': + resolution: {integrity: sha512-bO9fz25kKtPf+aZVyfQrC0PDmJdmVni31W2hCS5/Owb+inwdIL3XU26pCPRPlt4LSxZrBgLwubXQXQlKaFEZzw==} + peerDependencies: + '@types/react': ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + '@types/react': + optional: true + '@bruits/satteri-darwin-arm64@0.10.5': resolution: {integrity: sha512-27KTVl4TJkVahMy/ohyA7qd4938G5UNneFUz/PsScYfpIhj0IVAS23mpcJXdPF44sa6nva198lmV/cKIb2YPyA==} cpu: [arm64] @@ -892,6 +1080,28 @@ packages: '@data-slot/tooltip@1.0.2': resolution: {integrity: sha512-B++AfDWpbD8M7TRNs3Md5mF3ztgaDRHvBqBkSVOFti+9dx8xNRBUtficyixnew67Yqdxwu3DXVqEac1342WWnw==} + '@date-fns/tz@1.5.0': + resolution: {integrity: sha512-lwYN/vDPeNRULcepoE/LO2Pgx+7/RV+S9ARfbc9lr2DtGkOD7pAiruHvbR1RX3Qyf6ja47EWJDMsNK5vK08DJg==} + + '@daypicker/persian@10.0.2': + resolution: {integrity: sha512-GFT5n6WZoz2YIkmxINsiIyJXcSZg+X4a16hygs/SliZJRy3x0uJTWtZXnGrk7HBWIXILTScLCbRVBLza7DQZJw==} + peerDependencies: + '@types/react': '>=16.8.0' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + '@daypicker/react@10.0.2': + resolution: {integrity: sha512-Z/gvGXnc/xjRr5Z6l9OhIey00C7kwbIyJ85Pff9B9EWDkjTlkTQztB3qeylmGJDQ9xmxRJUV1W+02rskqarUBw==} + engines: {node: '>=18'} + peerDependencies: + '@types/react': '>=16.8.0' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + '@dotenvx/dotenvx@1.75.1': resolution: {integrity: sha512-/BITOC9dmS/edY2zQwZNicQ059O6RKabtQfyEafV0nGtfYRNHYy1DIPiYVcov40+tob9hfmBnbR963dS+EQ1DQ==} hasBin: true @@ -1139,6 +1349,24 @@ packages: resolution: {integrity: sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@floating-ui/core@1.8.0': + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} + + '@floating-ui/dom@1.8.0': + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} + + '@floating-ui/react-dom@2.1.9': + resolution: {integrity: sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.12': + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} + + '@fontsource-variable/vazirmatn@5.3.0': + resolution: {integrity: sha512-ZA68W8JHbMdNzzwjYHUWKB2PH22QpxNEnk0ukcXM+XiqYMV6ZWJZAKuNXcrMR2JjuIAwsfAU3KknCXPI6wXUvw==} + '@hono/node-server@2.1.3': resolution: {integrity: sha512-TA//nWMqPhbfdfneACk6t5a9eqbS9lABEPyKn0/xZTah3H3U2XaVg85rJFl0/Fyit0I552YDHgXGVSf3GwqbUw==} engines: {node: '>=20'} @@ -1681,6 +1909,179 @@ packages: '@prettier/parse-srcset@3.1.0': resolution: {integrity: sha512-FIRv2rZotO9NP/r66taYqD1zICpPiBbrECqjKV/xqNotqDxF7fLzzUeK+1RSRx9Tenk0DajR/GcRmTJ2qtHaKQ==} + '@radix-ui/primitive@1.1.7': + resolution: {integrity: sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q==} + + '@radix-ui/react-compose-refs@1.1.5': + resolution: {integrity: sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.2.2': + resolution: {integrity: sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.2.0': + resolution: {integrity: sha512-l5CX8HdNL+9cc4s7HkNyplumSA3FIx68sg9dttBHKr286fRBwq1MBniDVTeI/tkof92/APntMQvC1YG1Khb0Cg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.20': + resolution: {integrity: sha512-35WHRrycfnj2m4LvPiKMKHGLM3Y2WvUA744CkRdxjs1BGDX1c8PVMfmiSGTUwnHRbqdtIoxveYTXvcJSt7VfgQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.6': + resolution: {integrity: sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.2.0': + resolution: {integrity: sha512-I5S7vsAOozx2lWSBAyuXjWIJ/A8qx4fjbv6115WoaRYQSb1yZDaeNHonUAQzXyE8oD+0whJHbQRl4HIE2gQ0Xw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.4': + resolution: {integrity: sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-portal@1.1.18': + resolution: {integrity: sha512-ygFIJ+QXNKf72AAq8x3hd22+ws7pYpmc1S0E4kW0Je+qD4qEb3FvxeKVQRGrVDMOkQaYfsB+Qs+KDh81a1gAOw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.11': + resolution: {integrity: sha512-Z7/atlkab36Z8hm+V8zYc79r0W+tiOB1o0tun1By94JyadkekLQmtEAnBSP9XKXBNQsStoStS4+gX10JpS5akA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.11': + resolution: {integrity: sha512-RzcaSw5aKl0OPhBJ1wbolKSF6nVvN+0o/QLeIVq+09npiPdnCkPggy2k6gI6yetxl4ZyrlBPYFgCB8BQJZwXcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.4.0': + resolution: {integrity: sha512-IuMVHZ+Ah5fkctu3X3qeFrV/ZrBcuWuDTFUUPfS/L5hvoTjzhp/HdWGE14CsQombPdEidsa33HVlYZXi49PZ1Q==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.4': + resolution: {integrity: sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.6': + resolution: {integrity: sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.5': + resolution: {integrity: sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.4': + resolution: {integrity: sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@reduxjs/toolkit@2.13.0': + resolution: {integrity: sha512-f6jwVRfwW30+tnllz4YcsHHpPYYOE7abcHkyUCovD+P7DyhdAI5prz2Fh/8TLhakjpN+7aIEion1s5L/tvlYlA==} + peerDependencies: + react: ^16.9.0 || ^17.0.0 || ^18 || ^19 + react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0 + peerDependenciesMeta: + react: + optional: true + react-redux: + optional: true + '@rolldown/binding-android-arm-eabi@1.2.12': resolution: {integrity: sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1783,6 +2184,31 @@ packages: '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@shadcn/helpers@0.2.0': + resolution: {integrity: sha512-wpcZNuRgdW16jLwjvh4mbREKpVFrGY+nBM3Okgic8b04sijN5CHW1Nl/AEMajsP3INaCTNnqMCouOalZ7OHvEQ==} + peerDependencies: + '@tanstack/ai': '>=0.40.0 <0.41.0' + '@tanstack/ai-client': '>=0.20.0 <0.21.0' + ai: '>=7.0.0 <8' + peerDependenciesMeta: + '@tanstack/ai': + optional: true + '@tanstack/ai-client': + optional: true + ai: + optional: true + + '@shadcn/react@0.3.1': + resolution: {integrity: sha512-2gOR0HDMtWeRsCZfNDaU0YDFdgH3zsDQ6lz67Fv/y/qjY9y+R8kJqAn6q56phqv7/zHi0wqURjntrNO9zL7vnQ==} + peerDependencies: + '@types/react': '>=19' + react: '>=19' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + '@shadcn/registry@0.1.0': resolution: {integrity: sha512-eMF6tPNi9SWZgPvqBvPQFhJN7gV9PcjRdF3kPiiWo5yZJocWqVgxFuspCHrOij3bIJ797NIGZ+j/v7AiXfA6qg==} engines: {node: '>=20.18.1'} @@ -1828,6 +2254,26 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@standard-schema/utils@0.3.0': + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + + '@streamdown/code@2.0.0': + resolution: {integrity: sha512-sSyX/9gOOcivbP7204+sfAam+gotxjUNV+T4EuN3aa6i5x1LaqtB6Ln/Mxzd1XGvm0vNApO4oKLZs+7gzFI1kQ==} + engines: {node: '>=20'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + + '@tabler/icons-react@3.49.0': + resolution: {integrity: sha512-Um59pm5RVNUaQjFUtG0r4oYJbZuBS3tGugAA2tgBg0WufMk34Eio3nsO30RUkLuL2giYPQUNdY9HvqltLLYyNA==} + peerDependencies: + react: '>= 16' + + '@tabler/icons@3.49.0': + resolution: {integrity: sha512-l+GnSkFETx0U26icxv1VUFnxxiTqXfCcVRiRAnyMwibupM2S2L/hSaZ9gmSgz01rkrsH/93NvLsxykqdanc6lw==} + '@tailwindcss/node@4.3.3': resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} @@ -1922,12 +2368,58 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 + '@tanstack/react-store@0.11.2': + resolution: {integrity: sha512-oj5O5DmiMWE+ih+SioX2ayC1kbK7d3fpLx0B75fPJr9nY3zU+hoW010yr64qXsY/9fyiLVE2bn5mGNV3owm8RQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/react-table@9.2.8': + resolution: {integrity: sha512-cJxgratJm3uMm2sXnmY3PCTvcvIEFleCJ2uSOM2nxCmIY8RWA1KjXt5fsWGlYisL7DODr2w9YpLRQ3i/7MdIsQ==} + engines: {node: '>=20'} + peerDependencies: + react: '>=18' + + '@tanstack/store@0.11.2': + resolution: {integrity: sha512-sJ4mjol8uQsHV0gOJzzjwXfh2Fwm+Sz0+8deqiTm4jGbMdjzNSW+xZCFm0kUa870uhd8yi+DpKnZb5Kc4apa0Q==} + + '@tanstack/table-core@9.2.8': + resolution: {integrity: sha512-M4D6fY5jnc7z7TaoD3Pjvz5R+8MbhzCGYdkcFf2T1AgjigwLinvFWZh6mtqfN016A7yGIroOL0GiTlVGsTh6Vg==} + engines: {node: '>=20'} + '@ts-morph/common@0.27.0': resolution: {integrity: sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==} '@tybys/wasm-util@0.10.4': resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==} + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-shape@3.2.0': + resolution: {integrity: sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + '@types/debug@4.1.13': resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} @@ -1964,6 +2456,14 @@ packages: '@types/node@24.19.0': resolution: {integrity: sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew==} + '@types/react-dom@19.3.0': + resolution: {integrity: sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==} + peerDependencies: + '@types/react': ^19.3.0 + + '@types/react@19.3.0': + resolution: {integrity: sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==} + '@types/sax@1.2.7': resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} @@ -1976,6 +2476,9 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + '@types/validate-npm-package-name@4.0.2': resolution: {integrity: sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==} @@ -2041,6 +2544,26 @@ packages: '@ungap/structured-clone@1.4.0': resolution: {integrity: sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==} + '@vercel/oidc@3.2.0': + resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} + engines: {node: '>= 20'} + + '@vitejs/plugin-react@6.1.2': + resolution: {integrity: sha512-fhJNGUdscQa4HkI0xFxwonWyhnVReCPDbXI7FH7jmzpnVCrFQI7PRrhWecO263610vOrs9tr2Y4xcf8uAdFxbw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + oxc-transform-react: ^0.152.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + oxc-transform-react: + optional: true + '@volar/kit@2.4.28': resolution: {integrity: sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==} peerDependencies: @@ -2082,6 +2605,9 @@ packages: '@vscode/l10n@0.0.18': resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} + '@workflow/serde@4.1.0': + resolution: {integrity: sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==} + accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} @@ -2096,6 +2622,12 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + ai@7.0.136: + resolution: {integrity: sha512-quFXFKEw7qUZL9v2ciJ9eruQYq9KUo3F+mDhwdL/pi7ZPu0bj7UX6yv55oAUiMjbGXd8MZRzIcu0oPc4y9llQw==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + ajv-draft-04@1.0.0: resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} peerDependencies: @@ -2154,6 +2686,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} @@ -2347,6 +2883,10 @@ packages: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} + chrono-node@2.10.2: + resolution: {integrity: sha512-xBCwGGmodF2YVtzE7/8ewNDajbCg72jgZHyOXvhkuQiYhIQ1KbqyXJJJw2fLaQ603LL4oMVhOyjckEBve45S4w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + ci-info@4.4.0: resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} engines: {node: '>=8'} @@ -2370,6 +2910,12 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + cmdk@1.1.1: + resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + cn@0.2.6: resolution: {integrity: sha512-+i4L0zUGgRcEnhsxueVrP7iBGxBx5iD0WOTYg1MwFEu2ZyCmH5Ov2V1cul2Ht5UchRQQgftCf4be/RxspuW6QQ==} engines: {node: '>=20'} @@ -2485,6 +3031,53 @@ packages: resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-format@3.1.2: + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} @@ -2503,6 +3096,12 @@ packages: dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} + date-fns-jalali@4.1.0-0: + resolution: {integrity: sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==} + + date-fns@4.4.0: + resolution: {integrity: sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==} + debounce-fn@4.0.0: resolution: {integrity: sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==} engines: {node: '>=10'} @@ -2516,6 +3115,9 @@ packages: supports-color: optional: true + decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + decode-named-character-reference@1.3.0: resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} @@ -2580,6 +3182,9 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + devalue@5.9.4: resolution: {integrity: sha512-sPAT4pztbu6586/hrhOnMKS17IJrvg12mXiSPSS3W5qDeN2RGgvZ0diZCm31dBbnevfVmujNO3IM2wrS4Y2Rhg==} @@ -2661,6 +3266,21 @@ packages: peerDependencies: embla-carousel: 8.6.0 + embla-carousel-autoplay@8.6.0: + resolution: {integrity: sha512-OBu5G3nwaSXkZCo1A6LTaFMZ8EpkYbwIaH+bPqdBnDGQ2fh4+NbzjXjs2SktoPNKCtflfVMc75njaDHOYXcrsA==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-react@8.6.0: + resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} + peerDependencies: + react: ^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + + embla-carousel-reactive-utils@8.6.0: + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + embla-carousel@8.6.0: resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} @@ -2739,6 +3359,9 @@ packages: resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==} engines: {node: '>= 0.4'} + es-toolkit@1.52.0: + resolution: {integrity: sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==} + esast-util-from-estree@2.0.0: resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} @@ -2790,6 +3413,12 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + eslint-plugin-react-hooks@7.1.1: + resolution: {integrity: sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 + eslint-scope@9.1.2: resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -3009,6 +3638,17 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} + framer-motion@14.0.0: + resolution: {integrity: sha512-QAtHmybrDFSliyW1sexMtSQTQd+1jw2ajibEmzpuI4XdPVzQkn+dAzJMm2sW3pl9MJuSS4xN51djQ7huhlP/VA==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + fresh@2.0.0: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} @@ -3063,6 +3703,10 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-own-enumerable-keys@1.0.0: resolution: {integrity: sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==} engines: {node: '>=14.16'} @@ -3169,6 +3813,9 @@ packages: hast-util-raw@9.1.0: resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + hast-util-sanitize@5.0.2: + resolution: {integrity: sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==} + hast-util-to-estree@3.1.3: resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} @@ -3190,6 +3837,12 @@ packages: hastscript@9.0.1: resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + hono@4.13.12: resolution: {integrity: sha512-6E2QDAc9Ick9Sq77ZrGS/dk2WUYni91aufTw6LJKpV7w8kW5/GxVUc650FOADOmlwg3K+f7Pun6XlV+pYmW6gw==} engines: {node: '>=16.9.0'} @@ -3203,6 +3856,9 @@ packages: html-escaper@3.0.3: resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + html-validate@11.16.1: resolution: {integrity: sha512-PklC0d9tLeXpvC6INePZcTBlXplZOmBkR0IQTYoJ9TSrtqxBKR74lMdKPXcnOImD4mAdp/L5/QJR/x6WrvDYvA==} engines: {node: ^22.22.0 || >= 24.8.0} @@ -3263,6 +3919,12 @@ packages: resolution: {integrity: sha512-YChdK5txDjwGUvgR7oCJcLGkwi3LDh8Zx8tS7ndYciLEg/oOCL26VUBSUEtgS7EjiybcBqFxh5j0rAdDX7/bbg==} engines: {node: '>= 4'} + immer@10.2.0: + resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==} + + immer@11.1.21: + resolution: {integrity: sha512-bZSadeCPGdaY5/qRLgr6mDSH1ra21rD3rqpiWk7+QTr4ayYPTE9qZYdLh/NdPhMe0wSrTvHD/Lk8q5EwhUs0aw==} + import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -3277,10 +3939,20 @@ packages: inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + input-otp@1.5.0: + resolution: {integrity: sha512-3AcfdW1sNG0FmSA5hHMBXG7jNW5CdcdKs8ln8JOmn6S2SRkoXoJx+2UwC+ZvjflfnOdHJx0SfQ9/YjlxVYLtGQ==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + ip-address@10.7.2: resolution: {integrity: sha512-7H/2gFSIitxc0hG3nOI1glS8QLo/EHBFFLk8vEUjXY/xu0AdL8jZ9U1IzO2PUm0d2D/ofQcAifb0g6OBkt8U7w==} engines: {node: '>= 12'} @@ -3534,6 +4206,9 @@ packages: json-schema-typed@8.0.2: resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -3770,6 +4445,15 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lucide-react@1.53.0: + resolution: {integrity: sha512-OxJ7elNku+iqVzOolk5caxq2LM8Mck6lhA6uZx3g2PlZ53+FvBnT6PlJxGCukCa6oF5wQwgSatn9cH1b4olWmQ==} + peerDependencies: + '@types/react': '*' + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + lucide-static@1.49.0: resolution: {integrity: sha512-gSjtl7bR2v26oDInh2Wua1PrF2BRRXl9inhnLWcFfnRqRShmgZvlFRisPHqTfU7kxsuZU8ThNjAFotbInrzKow==} @@ -4030,6 +4714,23 @@ packages: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} + motion-dom@14.0.0: + resolution: {integrity: sha512-aU3ApXo1yTpeUi3JU+jbDk2TELjxPE3MbBMUP7nZHlARb6RweJK+ojmLjpuB0YsY6zhbBl1YWGo8LMsI1/Llqw==} + + motion-utils@14.0.0: + resolution: {integrity: sha512-jBsyjVxTTRZNeuvd/v+btVXr90LQkYl4HhRu9T2ARc+PMnvkmjsjRVeAg4Qm10b6TlTw+kykWI8gu/6LuvpLSQ==} + + motion@14.0.0: + resolution: {integrity: sha512-oGc2lkge2lkRZCP+J8/JsnYu4NFjqP1MtXirNdetn3QbvK2JqwM9A200EdT4C598KfzDhjLT12zF21xDM4Oilw==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -4060,6 +4761,12 @@ packages: resolution: {integrity: sha512-WmmLty1YWwJl9yZi77v2dVIV6X2kuYV8YYBI/G3LWGKdGHmHUvL1z7FW0iDvEvGAwNEoc5x1tOOOyDnf5jJw/w==} engines: {node: '>= 10'} + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + nlcst-to-string@4.0.0: resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} @@ -4492,6 +5199,82 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} + react-day-picker@10.0.2: + resolution: {integrity: sha512-QetiKtZWE9Uaw/pM/SYNv6WPYOTRnSJ2puL0GgwkmUFMIwiY0dtjH1W4B7DOVXVNQM0ZOClGpH/heOfBSzWeiA==} + engines: {node: '>=18'} + peerDependencies: + '@types/react': '>=16.8.0' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + react-dom@19.3.0: + resolution: {integrity: sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==} + peerDependencies: + react: ^19.3.0 + + react-is@19.3.0: + resolution: {integrity: sha512-UpMYezM4v5/18F28aC66AEsjXIgE02kyEMH6yLdgLXu/UTfa1Ntwck/nNLrbqJsEXW7gPb0coNO9FQse9WTovA==} + + react-redux@9.3.0: + resolution: {integrity: sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==} + peerDependencies: + '@types/react': ^18.2.25 || ^19 + react: ^18.0 || ^19 + redux: ^5.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + redux: + optional: true + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-resizable-panels@4.14.3: + resolution: {integrity: sha512-t/mJDWKBvc7sHcm/HJxJJKniqyQH6vK7oWyv8QODawYCcDwn0waBlGw0yFEwoMe6xPNKpbOFh2wN0yyina30ow==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-textarea-autosize@8.5.9: + resolution: {integrity: sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==} + engines: {node: '>=10'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + react@19.3.0: + resolution: {integrity: sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==} + engines: {node: '>=0.10.0'} + read-yaml-file@1.1.0: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} @@ -4508,6 +5291,14 @@ packages: resolution: {integrity: sha512-mFAyJq9vUbSTARLZUvAEf1z3YxlvAwswbmxMx2mPA/MSm4KmpwvwvhsH/NIrZhyOuwD60Lzyw2qh83uCbgTPYw==} engines: {node: '>= 4'} + recharts@3.8.0: + resolution: {integrity: sha512-Z/m38DX3L73ExO4Tpc9/iZWHmHnlzWG4njQbxsF5aSjwqmHNDDIm0rdEBArkwsBvR8U6EirlEHiQNYWCVh9sGQ==} + engines: {node: '>=18'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-is: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + recma-build-jsx@1.0.0: resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} @@ -4522,6 +5313,14 @@ packages: recma-stringify@1.0.0: resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + redux-thunk@3.1.0: + resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==} + peerDependencies: + redux: ^5.0.0 + + redux@5.0.1: + resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -4539,12 +5338,18 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + rehype-harden@1.1.8: + resolution: {integrity: sha512-Qn7vR1xrf6fZCrkm9TDWi/AB4ylrHy+jqsNm1EHOAmbARYA6gsnVJBq/sdBh6kmT4NEZxH5vgIjrscefJAOXcw==} + rehype-raw@7.0.0: resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} rehype-recma@1.0.0: resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + rehype-sanitize@6.0.0: + resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==} + rehype-stringify@10.0.1: resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} @@ -4567,6 +5372,9 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + remend@1.4.0: + resolution: {integrity: sha512-mHiYhhwphs1IgIZmkToKLwJn0U99IjPXuutkA2acrNcG0vlEq2G4TGnd2eT0saIHwh2KjaCpvleHcsd5SAz96A==} + request-light@0.5.8: resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==} @@ -4577,6 +5385,12 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + reselect@5.1.1: + resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} + + reselect@5.3.0: + resolution: {integrity: sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -4657,6 +5471,9 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} + scheduler@0.28.0: + resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -4766,6 +5583,16 @@ packages: resolution: {integrity: sha512-e0VyvkVTwVYViNovRkZ9aodhxVlyoMn7eJhVUPxZ+eK9P/7CBkxvvsBOHqFPEH416726W8tLXXXjKwqgTErrCQ==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + sonner@2.0.8: + resolution: {integrity: sha512-UM/ByIoFra8yzV75n1o0Puu0bw5U/9UNnDacrJNspekBewIfsQ3D6ez1nvlWpt7aTsO6rujQtifBpycwIivqlg==} + peerDependencies: + '@types/react': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + source-map-js@1.2.2: resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} engines: {node: '>=0.10.0'} @@ -4803,6 +5630,12 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + streamdown@2.7.0: + resolution: {integrity: sha512-SHYTCveHpRJfcIC8r+5EANczK21R0iNYo4i7wNaLeLeQjEnaVk4xMFhgV4E/mix69BpFSBui1NOESEXKlZfReA==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} @@ -4872,6 +5705,11 @@ packages: engines: {node: '>=16'} hasBin: true + swr@2.5.1: + resolution: {integrity: sha512-BRw55e8r0B7SpDN20CAzoQAHl7y1yP7/Zt7oqUjMv0vSt2u2Xnkm88Ws+VypbV9BXHQVuSuyVq7zMjO16wSExw==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + synckit@0.11.13: resolution: {integrity: sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==} engines: {node: ^14.18.0 || >=16.0.0} @@ -4882,6 +5720,9 @@ packages: os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true + tailwind-merge@3.7.0: + resolution: {integrity: sha512-XPPUyAc+cvspz3lHTcR/QgPfW2A0lv/xQNIjX3HGhLR+Nq2lHaLq5MtTesHn8GUr3W3DguT2KT5x3NVgRtYwmA==} + tailwindcss@4.3.3: resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} @@ -4893,6 +5734,10 @@ packages: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} + throttleit@2.1.0: + resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} + engines: {node: '>=18'} + tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} @@ -5144,6 +5989,58 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-composed-ref@1.4.0: + resolution: {integrity: sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + use-isomorphic-layout-effect@1.2.1: + resolution: {integrity: sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + use-latest@1.3.0: + resolution: {integrity: sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sync-external-store@1.7.0: + resolution: {integrity: sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -5172,6 +6069,9 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + victory-vendor@37.3.6: + resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==} + vite@8.3.2: resolution: {integrity: sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -5455,6 +6355,12 @@ packages: peerDependencies: zod: ^3.25.28 || ^4 + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -5466,6 +6372,46 @@ packages: snapshots: + '@ai-sdk/gateway@4.0.110(zod@4.6.5)': + dependencies: + '@ai-sdk/provider': 4.0.26 + '@ai-sdk/provider-utils': 5.0.58(zod@4.6.5) + '@vercel/oidc': 3.2.0 + zod: 4.6.5 + + '@ai-sdk/mcp@2.0.73(zod@4.6.5)': + dependencies: + '@ai-sdk/provider': 4.0.26 + '@ai-sdk/provider-utils': 5.0.58(zod@4.6.5) + cross-spawn: 7.0.6 + pkce-challenge: 5.0.1 + zod: 4.6.5 + + '@ai-sdk/provider-utils@5.0.58(zod@4.6.5)': + dependencies: + '@ai-sdk/provider': 4.0.26 + '@standard-schema/spec': 1.1.0 + '@workflow/serde': 4.1.0 + eventsource-parser: 3.1.1 + undici: 7.30.0 + zod: 4.6.5 + + '@ai-sdk/provider@4.0.26': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/react@4.0.139(react@19.3.0)(zod@4.6.5)': + dependencies: + '@ai-sdk/mcp': 2.0.73(zod@4.6.5) + '@ai-sdk/provider': 4.0.26 + '@ai-sdk/provider-utils': 5.0.58(zod@4.6.5) + ai: 7.0.136(zod@4.6.5) + react: 19.3.0 + swr: 2.5.1(react@19.3.0) + throttleit: 2.1.0 + transitivePeerDependencies: + - zod + '@astrojs/astro2tsx@0.1.2(@emnapi/runtime@1.11.3)': dependencies: '@emnapi/core': 1.11.3 @@ -5887,6 +6833,31 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 + '@base-ui/react@1.8.0(@date-fns/tz@1.5.0)(@types/react@19.3.0)(date-fns@4.4.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@babel/runtime': 7.29.7 + '@base-ui/utils': 0.4.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@floating-ui/react-dom': 2.1.9(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@floating-ui/utils': 0.2.12 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + use-sync-external-store: 1.7.0(react@19.3.0) + optionalDependencies: + '@date-fns/tz': 1.5.0 + '@types/react': 19.3.0 + date-fns: 4.4.0 + + '@base-ui/utils@0.4.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@babel/runtime': 7.29.7 + '@floating-ui/utils': 0.2.12 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + reselect: 5.3.0 + use-sync-external-store: 1.7.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + '@bruits/satteri-darwin-arm64@0.10.5': optional: true @@ -6190,6 +7161,24 @@ snapshots: dependencies: '@data-slot/core': 1.0.2 + '@date-fns/tz@1.5.0': {} + + '@daypicker/persian@10.0.2(@types/react@19.3.0)(react@19.3.0)': + dependencies: + '@date-fns/tz': 1.5.0 + '@daypicker/react': 10.0.2(@types/react@19.3.0)(react@19.3.0) + date-fns-jalali: 4.1.0-0 + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + + '@daypicker/react@10.0.2(@types/react@19.3.0)(react@19.3.0)': + dependencies: + react: 19.3.0 + react-day-picker: 10.0.2(@types/react@19.3.0)(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + '@dotenvx/dotenvx@1.75.1': dependencies: '@dotenvx/primitives': 0.8.0 @@ -6386,6 +7375,25 @@ snapshots: '@eslint/core': 1.2.1 levn: 0.4.1 + '@floating-ui/core@1.8.0': + dependencies: + '@floating-ui/utils': 0.2.12 + + '@floating-ui/dom@1.8.0': + dependencies: + '@floating-ui/core': 1.8.0 + '@floating-ui/utils': 0.2.12 + + '@floating-ui/react-dom@2.1.9(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@floating-ui/dom': 1.8.0 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + + '@floating-ui/utils@0.2.12': {} + + '@fontsource-variable/vazirmatn@5.3.0': {} + '@hono/node-server@2.1.3(hono@4.13.12)': dependencies: hono: 4.13.12 @@ -6776,36 +7784,185 @@ snapshots: '@oxc-resolver/binding-linux-x64-musl@11.24.2': optional: true - '@oxc-resolver/binding-openharmony-arm64@11.24.2': - optional: true + '@oxc-resolver/binding-openharmony-arm64@11.24.2': + optional: true + + '@oxc-resolver/binding-wasm32-wasi@11.24.2': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@napi-rs/wasm-runtime': 1.2.4(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) + optional: true + + '@oxc-resolver/binding-win32-arm64-msvc@11.24.2': + optional: true + + '@oxc-resolver/binding-win32-x64-msvc@11.24.2': + optional: true + + '@pkgr/core@0.3.6': {} + + '@posthog/browser-common@0.9.1': + dependencies: + '@posthog/core': 1.55.3 + '@posthog/types': 1.413.0 + + '@posthog/core@1.55.3': + dependencies: + '@posthog/types': 1.413.0 + + '@posthog/types@1.413.0': {} + + '@prettier/parse-srcset@3.1.0': {} + + '@radix-ui/primitive@1.1.7': {} + + '@radix-ui/react-compose-refs@1.1.5(@types/react@19.3.0)(react@19.3.0)': + dependencies: + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + + '@radix-ui/react-context@1.2.2(@types/react@19.3.0)(react@19.3.0)': + dependencies: + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + + '@radix-ui/react-dialog@1.2.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@radix-ui/primitive': 1.1.7 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-context': 1.2.2(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-dismissable-layer': 1.1.20(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@radix-ui/react-focus-guards': 1.1.6(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-focus-scope': 1.2.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@radix-ui/react-id': 1.1.4(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-portal': 1.1.18(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@radix-ui/react-presence': 1.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@radix-ui/react-primitive': 2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@radix-ui/react-slot': 1.4.0(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0) + aria-hidden: 1.2.6 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + react-remove-scroll: 2.7.2(@types/react@19.3.0)(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + '@types/react-dom': 19.3.0(@types/react@19.3.0) + + '@radix-ui/react-dismissable-layer@1.1.20(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@radix-ui/primitive': 1.1.7 + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-primitive': 2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-use-effect-event': 0.0.5(@types/react@19.3.0)(react@19.3.0) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + '@types/react-dom': 19.3.0(@types/react@19.3.0) + + '@radix-ui/react-focus-guards@1.1.6(@types/react@19.3.0)(react@19.3.0)': + dependencies: + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + + '@radix-ui/react-focus-scope@1.2.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-primitive': 2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.3.0)(react@19.3.0) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + '@types/react-dom': 19.3.0(@types/react@19.3.0) + + '@radix-ui/react-id@1.1.4(@types/react@19.3.0)(react@19.3.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0) + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 - '@oxc-resolver/binding-wasm32-wasi@11.24.2': + '@radix-ui/react-portal@1.1.18(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': dependencies: - '@emnapi/core': 1.11.2 - '@emnapi/runtime': 1.11.2 - '@napi-rs/wasm-runtime': 1.2.4(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) - optional: true + '@radix-ui/react-primitive': 2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + '@types/react-dom': 19.3.0(@types/react@19.3.0) - '@oxc-resolver/binding-win32-arm64-msvc@11.24.2': - optional: true + '@radix-ui/react-presence@1.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + '@types/react-dom': 19.3.0(@types/react@19.3.0) - '@oxc-resolver/binding-win32-x64-msvc@11.24.2': - optional: true + '@radix-ui/react-primitive@2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@radix-ui/react-slot': 1.4.0(@types/react@19.3.0)(react@19.3.0) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + '@types/react-dom': 19.3.0(@types/react@19.3.0) - '@pkgr/core@0.3.6': {} + '@radix-ui/react-slot@1.4.0(@types/react@19.3.0)(react@19.3.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.3.0)(react@19.3.0) + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 - '@posthog/browser-common@0.9.1': + '@radix-ui/react-use-callback-ref@1.1.4(@types/react@19.3.0)(react@19.3.0)': dependencies: - '@posthog/core': 1.55.3 - '@posthog/types': 1.413.0 + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 - '@posthog/core@1.55.3': + '@radix-ui/react-use-controllable-state@1.2.6(@types/react@19.3.0)(react@19.3.0)': dependencies: - '@posthog/types': 1.413.0 + '@radix-ui/primitive': 1.1.7 + '@radix-ui/react-use-effect-event': 0.0.5(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0) + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 - '@posthog/types@1.413.0': {} + '@radix-ui/react-use-effect-event@0.0.5(@types/react@19.3.0)(react@19.3.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.3.0)(react@19.3.0) + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 - '@prettier/parse-srcset@3.1.0': {} + '@radix-ui/react-use-layout-effect@1.1.4(@types/react@19.3.0)(react@19.3.0)': + dependencies: + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + + '@reduxjs/toolkit@2.13.0(react-redux@9.3.0(@types/react@19.3.0)(react@19.3.0)(redux@5.0.1))(react@19.3.0)': + dependencies: + '@standard-schema/spec': 1.1.0 + '@standard-schema/utils': 0.3.0 + immer: 11.1.21 + redux: 5.0.1 + redux-thunk: 3.1.0(redux@5.0.1) + reselect: 5.1.1 + optionalDependencies: + react: 19.3.0 + react-redux: 9.3.0(@types/react@19.3.0)(react@19.3.0)(redux@5.0.1) '@rolldown/binding-android-arm-eabi@1.2.12': optional: true @@ -6856,6 +8013,15 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} + '@shadcn/helpers@0.2.0(ai@7.0.136(zod@4.6.5))': + optionalDependencies: + ai: 7.0.136(zod@4.6.5) + + '@shadcn/react@0.3.1(@types/react@19.3.0)(react@19.3.0)': + optionalDependencies: + '@types/react': 19.3.0 + react: 19.3.0 + '@shadcn/registry@0.1.0(typescript@6.0.3)': dependencies: '@babel/core': 7.29.7 @@ -6932,6 +8098,22 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} + '@standard-schema/spec@1.1.0': {} + + '@standard-schema/utils@0.3.0': {} + + '@streamdown/code@2.0.0(react@19.3.0)': + dependencies: + react: 19.3.0 + shiki: 4.5.0 + + '@tabler/icons-react@3.49.0(react@19.3.0)': + dependencies: + '@tabler/icons': 3.49.0 + react: 19.3.0 + + '@tabler/icons@3.49.0': {} + '@tailwindcss/node@4.3.3': dependencies: '@jridgewell/remapping': 2.3.5 @@ -7000,6 +8182,27 @@ snapshots: tailwindcss: 4.3.3 vite: 8.3.2(@types/node@24.19.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1) + '@tanstack/react-store@0.11.2(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/store': 0.11.2 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + use-sync-external-store: 1.7.0(react@19.3.0) + + '@tanstack/react-table@9.2.8(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/react-store': 0.11.2(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/table-core': 9.2.8 + react: 19.3.0 + transitivePeerDependencies: + - react-dom + + '@tanstack/store@0.11.2': {} + + '@tanstack/table-core@9.2.8': + dependencies: + '@tanstack/store': 0.11.2 + '@ts-morph/common@0.27.0': dependencies: fast-glob: 3.3.3 @@ -7010,6 +8213,30 @@ snapshots: dependencies: tslib: 2.8.1 + '@types/d3-array@3.2.2': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-shape@3.2.0': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + '@types/debug@4.1.13': dependencies: '@types/ms': 2.1.0 @@ -7046,6 +8273,14 @@ snapshots: dependencies: undici-types: 7.24.6 + '@types/react-dom@19.3.0(@types/react@19.3.0)': + dependencies: + '@types/react': 19.3.0 + + '@types/react@19.3.0': + dependencies: + csstype: 3.2.3 + '@types/sax@1.2.7': dependencies: '@types/node': 24.19.0 @@ -7057,6 +8292,8 @@ snapshots: '@types/unist@3.0.3': {} + '@types/use-sync-external-store@0.0.6': {} + '@types/validate-npm-package-name@4.0.2': {} '@typescript-eslint/eslint-plugin@8.71.0(@typescript-eslint/parser@8.71.0(eslint@10.11.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.11.0(jiti@2.7.0))(typescript@6.0.3)': @@ -7152,6 +8389,13 @@ snapshots: '@ungap/structured-clone@1.4.0': {} + '@vercel/oidc@3.2.0': {} + + '@vitejs/plugin-react@6.1.2(vite@8.3.2(@types/node@24.19.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@rolldown/pluginutils': 1.0.1 + vite: 8.3.2(@types/node@24.19.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1) + '@volar/kit@2.4.28(typescript@6.0.3)': dependencies: '@volar/language-service': 2.4.28(typescript@6.0.3) @@ -7208,6 +8452,8 @@ snapshots: '@vscode/l10n@0.0.18': {} + '@workflow/serde@4.1.0': {} + accepts@2.0.0: dependencies: mime-types: 3.0.2 @@ -7219,6 +8465,13 @@ snapshots: acorn@8.18.0: {} + ai@7.0.136(zod@4.6.5): + dependencies: + '@ai-sdk/gateway': 4.0.110(zod@4.6.5) + '@ai-sdk/provider': 4.0.26 + '@ai-sdk/provider-utils': 5.0.58(zod@4.6.5) + zod: 4.6.5 + ajv-draft-04@1.0.0(ajv@8.20.0): optionalDependencies: ajv: 8.20.0 @@ -7274,6 +8527,10 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + aria-query@5.3.2: {} array-buffer-byte-length@1.0.2: @@ -7571,6 +8828,8 @@ snapshots: dependencies: readdirp: 5.1.1 + chrono-node@2.10.2: {} + ci-info@4.4.0: {} class-variance-authority@0.7.1: @@ -7591,6 +8850,18 @@ snapshots: clsx@2.1.1: {} + cmdk@1.1.1(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-dialog': 1.2.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@radix-ui/react-id': 1.1.4(@types/react@19.3.0)(react@19.3.0) + '@radix-ui/react-primitive': 2.1.11(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + cn@0.2.6: {} cn@0.4.0: {} @@ -7690,6 +8961,46 @@ snapshots: dependencies: css-tree: 2.2.1 + csstype@3.2.3: {} + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-color@3.1.0: {} + + d3-ease@3.0.1: {} + + d3-format@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@3.1.0: {} + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.2 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + damerau-levenshtein@1.0.8: {} data-view-buffer@1.0.2: @@ -7712,6 +9023,10 @@ snapshots: dataloader@1.4.0: {} + date-fns-jalali@4.1.0-0: {} + + date-fns@4.4.0: {} + debounce-fn@4.0.0: dependencies: mimic-fn: 3.1.0 @@ -7720,6 +9035,8 @@ snapshots: dependencies: ms: 2.1.3 + decimal.js-light@2.5.1: {} + decode-named-character-reference@1.3.0: dependencies: character-entities: 2.0.2 @@ -7765,6 +9082,8 @@ snapshots: detect-libc@2.1.2: {} + detect-node-es@1.1.0: {} + devalue@5.9.4: {} devlop@1.1.0: @@ -7843,6 +9162,20 @@ snapshots: dependencies: embla-carousel: 8.6.0 + embla-carousel-autoplay@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-react@8.6.0(react@19.3.0): + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + react: 19.3.0 + + embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + embla-carousel@8.6.0: {} emmet@2.4.11: @@ -7972,6 +9305,8 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + es-toolkit@1.52.0: {} + esast-util-from-estree@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 @@ -8061,6 +9396,17 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 + eslint-plugin-react-hooks@7.1.1(eslint@10.11.0(jiti@2.7.0)): + dependencies: + '@babel/core': 7.29.7 + '@babel/parser': 7.29.9 + eslint: 10.11.0(jiti@2.7.0) + hermes-parser: 0.25.1 + zod: 4.6.5 + zod-validation-error: 4.0.2(zod@4.6.5) + transitivePeerDependencies: + - supports-color + eslint-scope@9.1.2: dependencies: '@types/esrecurse': 4.3.1 @@ -8362,6 +9708,15 @@ snapshots: forwarded@0.2.0: {} + framer-motion@14.0.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + motion-dom: 14.0.0 + motion-utils: 14.0.0 + tslib: 2.8.1 + optionalDependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + fresh@2.0.0: {} fs-extra@11.4.1: @@ -8424,6 +9779,8 @@ snapshots: hasown: 2.0.4 math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} + get-own-enumerable-keys@1.0.0: {} get-proto@1.0.1: @@ -8568,6 +9925,12 @@ snapshots: web-namespaces: 2.0.1 zwitch: 2.0.4 + hast-util-sanitize@5.0.2: + dependencies: + '@types/hast': 3.0.5 + '@ungap/structured-clone': 1.4.0 + unist-util-position: 5.0.0 + hast-util-to-estree@3.1.3: dependencies: '@types/estree': 1.0.9 @@ -8652,6 +10015,12 @@ snapshots: property-information: 7.2.0 space-separated-tokens: 2.0.2 + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + hono@4.13.12: {} hookified@1.15.1: {} @@ -8660,6 +10029,8 @@ snapshots: html-escaper@3.0.3: {} + html-url-attributes@3.0.1: {} + html-validate@11.16.1: dependencies: '@html-validate/stylish': 6.0.0 @@ -8702,6 +10073,10 @@ snapshots: ignore@7.0.11: {} + immer@10.2.0: {} + + immer@11.1.21: {} + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -8713,12 +10088,19 @@ snapshots: inline-style-parser@0.2.7: {} + input-otp@1.5.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 hasown: 2.0.4 side-channel: 1.1.1 + internmap@2.0.3: {} + ip-address@10.7.2: {} ipaddr.js@1.9.1: {} @@ -8925,6 +10307,8 @@ snapshots: json-schema-typed@8.0.2: {} + json-schema@0.4.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} json5@2.2.3: {} @@ -9127,6 +10511,12 @@ snapshots: dependencies: yallist: 3.1.1 + lucide-react@1.53.0(@types/react@19.3.0)(react@19.3.0): + dependencies: + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + lucide-static@1.49.0: {} magic-string@0.30.21: @@ -9642,6 +11032,20 @@ snapshots: minipass@7.1.3: {} + motion-dom@14.0.0: + dependencies: + motion-utils: 14.0.0 + + motion-utils@14.0.0: {} + + motion@14.0.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + framer-motion: 14.0.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + tslib: 2.8.1 + optionalDependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + mri@1.2.0: {} mrmime@2.0.1: {} @@ -9660,6 +11064,11 @@ snapshots: neotraverse@1.0.1: {} + next-themes@0.4.6(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + nlcst-to-string@4.0.0: dependencies: '@types/nlcst': 2.0.3 @@ -9982,7 +11391,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.2 - posthog-js@1.434.15: + posthog-js@1.434.15(@types/react@19.3.0)(react@19.3.0): dependencies: '@posthog/browser-common': 0.9.1 '@posthog/core': 1.55.3 @@ -9994,6 +11403,9 @@ snapshots: query-selector-shadow-dom: 1.0.1 web-vitals: 6.2.2 web-vitals-soft-navs: web-vitals@6.2.1 + optionalDependencies: + '@types/react': 19.3.0 + react: 19.3.0 transitivePeerDependencies: - preact-render-to-string @@ -10072,6 +11484,73 @@ snapshots: iconv-lite: 0.7.3 unpipe: 1.0.0 + react-day-picker@10.0.2(@types/react@19.3.0)(react@19.3.0): + dependencies: + '@date-fns/tz': 1.5.0 + date-fns: 4.4.0 + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + + react-dom@19.3.0(react@19.3.0): + dependencies: + react: 19.3.0 + scheduler: 0.28.0 + + react-is@19.3.0: {} + + react-redux@9.3.0(@types/react@19.3.0)(react@19.3.0)(redux@5.0.1): + dependencies: + '@types/use-sync-external-store': 0.0.6 + react: 19.3.0 + use-sync-external-store: 1.7.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + redux: 5.0.1 + + react-remove-scroll-bar@2.3.8(@types/react@19.3.0)(react@19.3.0): + dependencies: + react: 19.3.0 + react-style-singleton: 2.2.3(@types/react@19.3.0)(react@19.3.0) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.3.0 + + react-remove-scroll@2.7.2(@types/react@19.3.0)(react@19.3.0): + dependencies: + react: 19.3.0 + react-remove-scroll-bar: 2.3.8(@types/react@19.3.0)(react@19.3.0) + react-style-singleton: 2.2.3(@types/react@19.3.0)(react@19.3.0) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.3.0)(react@19.3.0) + use-sidecar: 1.1.3(@types/react@19.3.0)(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + + react-resizable-panels@4.14.3(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + + react-style-singleton@2.2.3(@types/react@19.3.0)(react@19.3.0): + dependencies: + get-nonce: 1.0.1 + react: 19.3.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.3.0 + + react-textarea-autosize@8.5.9(@types/react@19.3.0)(react@19.3.0): + dependencies: + '@babel/runtime': 7.29.7 + react: 19.3.0 + use-composed-ref: 1.4.0(@types/react@19.3.0)(react@19.3.0) + use-latest: 1.3.0(@types/react@19.3.0)(react@19.3.0) + transitivePeerDependencies: + - '@types/react' + + react@19.3.0: {} + read-yaml-file@1.1.0: dependencies: graceful-fs: 4.2.11 @@ -10091,6 +11570,26 @@ snapshots: tiny-invariant: 1.3.3 tslib: 2.8.1 + recharts@3.8.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react-is@19.3.0)(react@19.3.0)(redux@5.0.1): + dependencies: + '@reduxjs/toolkit': 2.13.0(react-redux@9.3.0(@types/react@19.3.0)(react@19.3.0)(redux@5.0.1))(react@19.3.0) + clsx: 2.1.1 + decimal.js-light: 2.5.1 + es-toolkit: 1.52.0 + eventemitter3: 5.0.4 + immer: 10.2.0 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + react-is: 19.3.0 + react-redux: 9.3.0(@types/react@19.3.0)(react@19.3.0)(redux@5.0.1) + reselect: 5.1.1 + tiny-invariant: 1.3.3 + use-sync-external-store: 1.7.0(react@19.3.0) + victory-vendor: 37.3.6 + transitivePeerDependencies: + - '@types/react' + - redux + recma-build-jsx@1.0.0: dependencies: '@types/estree': 1.0.9 @@ -10120,6 +11619,12 @@ snapshots: unified: 11.0.5 vfile: 6.0.3 + redux-thunk@3.1.0(redux@5.0.1): + dependencies: + redux: 5.0.1 + + redux@5.0.1: {} + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.9 @@ -10150,6 +11655,10 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + rehype-harden@1.1.8: + dependencies: + unist-util-visit: 5.1.0 + rehype-raw@7.0.0: dependencies: '@types/hast': 3.0.5 @@ -10164,6 +11673,11 @@ snapshots: transitivePeerDependencies: - supports-color + rehype-sanitize@6.0.0: + dependencies: + '@types/hast': 3.0.5 + hast-util-sanitize: 5.0.2 + rehype-stringify@10.0.1: dependencies: '@types/hast': 3.0.5 @@ -10218,12 +11732,18 @@ snapshots: mdast-util-to-markdown: 2.1.3 unified: 11.0.5 + remend@1.4.0: {} + request-light@0.5.8: {} request-light@0.7.0: {} require-from-string@2.0.2: {} + reselect@5.1.1: {} + + reselect@5.3.0: {} + resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -10349,6 +11869,8 @@ snapshots: dependencies: xmlchars: 2.2.0 + scheduler@0.28.0: {} + semver@6.3.1: {} semver@7.8.5: {} @@ -10548,6 +12070,13 @@ snapshots: ip-address: 10.7.2 smart-buffer: 4.2.0 + sonner@2.0.8(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + source-map-js@1.2.2: {} source-map@0.6.1: {} @@ -10574,6 +12103,28 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + streamdown@2.7.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + clsx: 2.1.1 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + marked: 18.1.0 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + rehype-harden: 1.1.8 + rehype-raw: 7.0.0 + rehype-sanitize: 6.0.0 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remend: 1.4.0 + tailwind-merge: 3.7.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color + string-width@7.2.0: dependencies: emoji-regex: 10.6.0 @@ -10664,18 +12215,28 @@ snapshots: picocolors: 1.1.1 sax: 1.6.1 + swr@2.5.1(react@19.3.0): + dependencies: + dequal: 2.0.3 + react: 19.3.0 + use-sync-external-store: 1.7.0(react@19.3.0) + synckit@0.11.13: dependencies: '@pkgr/core': 0.3.6 systeminformation@5.33.15: {} + tailwind-merge@3.7.0: {} + tailwindcss@4.3.3: {} tapable@2.3.3: {} term-size@2.2.1: {} + throttleit@2.1.0: {} + tiny-inflate@1.0.3: {} tiny-invariant@1.3.3: {} @@ -10895,6 +12456,44 @@ snapshots: dependencies: punycode: 2.3.1 + use-callback-ref@1.3.3(@types/react@19.3.0)(react@19.3.0): + dependencies: + react: 19.3.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.3.0 + + use-composed-ref@1.4.0(@types/react@19.3.0)(react@19.3.0): + dependencies: + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + + use-isomorphic-layout-effect@1.2.1(@types/react@19.3.0)(react@19.3.0): + dependencies: + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + + use-latest@1.3.0(@types/react@19.3.0)(react@19.3.0): + dependencies: + react: 19.3.0 + use-isomorphic-layout-effect: 1.2.1(@types/react@19.3.0)(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + + use-sidecar@1.1.3(@types/react@19.3.0)(react@19.3.0): + dependencies: + detect-node-es: 1.1.0 + react: 19.3.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.3.0 + + use-sync-external-store@1.7.0(react@19.3.0): + dependencies: + react: 19.3.0 + util-deprecate@1.0.2: {} valid-filename@4.0.0: @@ -10922,6 +12521,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 + victory-vendor@37.3.6: + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-ease': 3.0.2 + '@types/d3-interpolate': 3.0.4 + '@types/d3-scale': 4.0.9 + '@types/d3-shape': 3.2.0 + '@types/d3-time': 3.0.4 + '@types/d3-timer': 3.0.2 + d3-array: 3.2.4 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-scale: 4.0.2 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-timer: 3.0.1 + vite@8.3.2(@types/node@24.19.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1): dependencies: lightningcss: 1.33.0 @@ -11186,6 +12802,10 @@ snapshots: dependencies: zod: 3.25.76 + zod-validation-error@4.0.2(zod@4.6.5): + dependencies: + zod: 4.6.5 + zod@3.25.76: {} zod@4.6.5: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index d1e17c3b4..ad26fceb9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,9 @@ +# The React port lives in its own package, so its dependencies stay out of the +# published Astro package. The root stays a workspace package for Changesets. +packages: + - "." + - react + # No dependency runs install scripts, here, in CI or on Netlify. esbuild and sharp # ship prebuilt binaries as optional dependencies. allowBuilds: diff --git a/public/r/accordion-examples.json b/public/r/accordion-examples.json new file mode 100644 index 000000000..030914be4 --- /dev/null +++ b/public/r/accordion-examples.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "accordion-examples", + "title": "Accordion examples", + "description": "The examples from the shadcn/ui Accordion docs.", + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/card" + ], + "files": [ + { + "path": "src/components/examples/accordion/accordion-basic.astro", + "content": "---\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n\nconst items = [\n {\n value: \"item-1\",\n trigger: \"How do I reset my password?\",\n content:\n \"Click on 'Forgot Password' on the login page, enter your email address, and we'll send you a link to reset your password. The link will expire in 24 hours.\",\n },\n {\n value: \"item-2\",\n trigger: \"Can I change my subscription plan?\",\n content:\n \"Yes, you can upgrade or downgrade your plan at any time from your account settings. Changes will be reflected in your next billing cycle.\",\n },\n {\n value: \"item-3\",\n trigger: \"What payment methods do you accept?\",\n content:\n \"We accept all major credit cards, PayPal, and bank transfers. All payments are processed securely through our payment partners.\",\n },\n]\n---\n\n\n {items.map((item) => (\n \n {item.trigger}\n {item.content}\n \n ))}\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-borders.astro", + "content": "---\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n\nconst items = [\n {\n value: \"billing\",\n trigger: \"How does billing work?\",\n content:\n \"We offer monthly and annual subscription plans. Billing is charged at the beginning of each cycle, and you can cancel anytime. All plans include automatic backups, 24/7 support, and unlimited team members.\",\n },\n {\n value: \"security\",\n trigger: \"Is my data secure?\",\n content:\n \"Yes. We use end-to-end encryption, SOC 2 Type II compliance, and regular third-party security audits. All data is encrypted at rest and in transit using industry-standard protocols.\",\n },\n {\n value: \"integration\",\n trigger: \"What integrations do you support?\",\n content:\n \"We integrate with 500+ popular tools including Slack, Zapier, Salesforce, HubSpot, and more. You can also build custom integrations using our REST API and webhooks.\",\n },\n]\n---\n\n\n {items.map((item) => (\n \n {item.trigger}\n {item.content}\n \n ))}\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-card.astro", + "content": "---\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\n\nconst items = [\n {\n value: \"plans\",\n trigger: \"What subscription plans do you offer?\",\n content:\n \"We offer three subscription tiers: Starter ($9/month), Professional ($29/month), and Enterprise ($99/month). Each plan includes increasing storage limits, API access, priority support, and team collaboration features.\",\n },\n {\n value: \"billing\",\n trigger: \"How does billing work?\",\n content:\n \"Billing occurs automatically at the start of each billing cycle. We accept all major credit cards, PayPal, and ACH transfers for enterprise customers. You'll receive an invoice via email after each payment.\",\n },\n {\n value: \"cancel\",\n trigger: \"How do I cancel my subscription?\",\n content:\n \"You can cancel your subscription anytime from your account settings. There are no cancellation fees or penalties. Your access will continue until the end of your current billing period.\",\n },\n]\n---\n\n\n \n Subscription & Billing\n \n Common questions about your account, plans, payments and cancellations.\n \n \n \n \n {items.map((item) => (\n \n {item.trigger}\n {item.content}\n \n ))}\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-demo.astro", + "content": "---\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n---\n\n\n \n What are your shipping options?\n \n We offer standard (5-7 days), express (2-3 days), and overnight shipping.\n Free shipping on international orders.\n \n \n \n What is your return policy?\n \n Returns accepted within 30 days. Items must be unused and in original\n packaging. Refunds processed within 5-7 business days.\n \n \n \n How can I contact customer support?\n \n Reach us via email, live chat, or phone. We respond within 24 hours during\n business days.\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-disabled.astro", + "content": "---\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n---\n\n\n \n Can I access my account history?\n \n Yes, you can view your complete account history including all\n transactions, plan changes, and support tickets in the Account History\n section of your dashboard.\n \n \n \n Premium feature information\n \n This section contains information about premium features. Upgrade your\n plan to access this content.\n \n \n \n How do I update my email address?\n \n You can update your email address in your account settings. You'll receive\n a verification email at your new address to confirm the change.\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-multiple.astro", + "content": "---\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n\nconst items = [\n {\n value: \"notifications\",\n trigger: \"Notification Settings\",\n content:\n \"Manage how you receive notifications. You can enable email alerts for updates or push notifications for mobile devices.\",\n },\n {\n value: \"privacy\",\n trigger: \"Privacy & Security\",\n content:\n \"Control your privacy settings and security preferences. Enable two-factor authentication, manage connected devices, review active sessions, and configure data sharing preferences. You can also download your data or delete your account.\",\n },\n {\n value: \"billing\",\n trigger: \"Billing & Subscription\",\n content:\n \"View your current plan, payment history, and upcoming invoices. Update your payment method, change your subscription tier, or cancel your subscription.\",\n },\n]\n---\n\n\n {items.map((item) => (\n \n {item.trigger}\n {item.content}\n \n ))}\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-rtl.astro", + "content": "---\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n question1: \"How do I reset my password?\",\n answer1:\n \"Click on 'Forgot Password' on the login page, enter your email address, and we'll send you a link to reset your password.\",\n question2: \"Can I change my subscription plan?\",\n answer2:\n \"Yes, you can upgrade or downgrade your plan at any time from your account settings. Changes will be reflected in your next billing cycle.\",\n question3: \"What payment methods do you accept?\",\n answer3:\n \"We accept all major credit cards, PayPal, and bank transfers. All payments are processed securely through our payment partners.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n question1: \"كيف يمكنني إعادة تعيين كلمة المرور؟\",\n answer1:\n \"انقر على 'نسيت كلمة المرور' في صفحة تسجيل الدخول، أدخل عنوان بريدك الإلكتروني، وسنرسل لك رابطًا لإعادة تعيين كلمة المرور. سينتهي صلاحية الرابط خلال 24 ساعة.\",\n question2: \"هل يمكنني تغيير خطة الاشتراك الخاصة بي؟\",\n answer2:\n \"نعم، يمكنك ترقية أو تخفيض خطتك في أي وقت من إعدادات حسابك. ستظهر التغييرات في دورة الفوترة التالية.\",\n question3: \"ما هي طرق الدفع التي تقبلونها؟\",\n answer3:\n \"نقبل جميع بطاقات الائتمان الرئيسية و PayPal والتحويلات المصرفية. تتم معالجة جميع المدفوعات بأمان من خلال شركاء الدفع لدينا.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n question1: \"איך אני מאפס את הסיסמה שלי?\",\n answer1:\n \"לחץ על 'שכחתי סיסמה' בעמוד ההתחברות, הזן את כתובת האימייל שלך, ונשלח לך קישור לאיפוס הסיסמה. הקישור יפוג תוך 24 שעות.\",\n question2: \"האם אני יכול לשנות את תוכנית המנוי שלי?\",\n answer2:\n \"כן, אתה יכול לשדרג או להוריד את התוכנית שלך בכל עת מההגדרות של החשבון שלך. השינויים יבואו לידי ביטוי במחזור החיוב הבא.\",\n question3: \"אילו אמצעי תשלום אתם מקבלים?\",\n answer3: \"אנו מקבלים כרטיסי אשראי, PayPal והעברות בנקאיות.\",\n },\n },\n} as const\n\nconst items = [\n { value: \"item-1\", questionKey: \"question1\", answerKey: \"answer1\" },\n { value: \"item-2\", questionKey: \"question2\", answerKey: \"answer2\" },\n { value: \"item-3\", questionKey: \"question3\", answerKey: \"answer3\" },\n] as const\n\nconst { dir, values: t } = translations.ar\n---\n\n\n {items.map((item) => (\n \n {t[item.questionKey]}\n {t[item.answerKey]}\n \n ))}\n\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/accordion/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/accordion.json b/public/r/accordion.json index c8c8db7cc..2f08cd482 100644 --- a/public/r/accordion.json +++ b/public/r/accordion.json @@ -34,7 +34,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/accordion/", + "docs": "https://ui.full.dev/astro/components/accordion/", "categories": [ "ui" ], diff --git a/public/r/alert-dialog-examples.json b/public/r/alert-dialog-examples.json new file mode 100644 index 000000000..4d049371d --- /dev/null +++ b/public/r/alert-dialog-examples.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "alert-dialog-examples", + "title": "Alert Dialog examples", + "description": "The examples from the shadcn/ui Alert Dialog docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/alert-dialog" + ], + "files": [ + { + "path": "src/components/examples/alert-dialog/alert-dialog-basic.astro", + "content": "---\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\n---\n\n\n Show Dialog\n \n \n Are you absolutely sure?\n \n This action cannot be undone. This will permanently delete your account\n and remove your data from our servers.\n \n \n \n Cancel\n Continue\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-demo.astro", + "content": "---\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\n---\n\n\n Show Dialog\n \n \n Are you absolutely sure?\n \n This action cannot be undone. This will permanently delete your account\n from our servers.\n \n \n \n Cancel\n Continue\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-destructive.astro", + "content": "---\nimport Trash2Icon from \"@lucide/astro/icons/trash\"\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\n---\n\n\n Delete Chat\n \n \n \n \n \n Delete chat?\n \n This will permanently delete this chat conversation. View\n Settings delete any memories saved during this chat.\n \n \n \n Cancel\n Delete\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-media.astro", + "content": "---\nimport CircleFadingPlusIcon from \"@lucide/astro/icons/circle-fading-plus\"\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\n---\n\n\n Share Project\n \n \n \n \n \n Share this project?\n \n Anyone with the link will be able to view and edit this project.\n \n \n \n Cancel\n Share\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-rtl.astro", + "content": "---\nimport BluetoothIcon from \"@lucide/astro/icons/bluetooth\"\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n showDialog: \"Show Dialog\",\n showDialogSm: \"Show Dialog (sm)\",\n title: \"Are you absolutely sure?\",\n description:\n \"This action cannot be undone. This will permanently delete your account from our servers.\",\n cancel: \"Cancel\",\n continue: \"Continue\",\n smallTitle: \"Allow accessory to connect?\",\n smallDescription:\n \"Do you want to allow the USB accessory to connect to this device?\",\n dontAllow: \"Don't allow\",\n allow: \"Allow\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n showDialog: \"إظهار الحوار\",\n showDialogSm: \"إظهار الحوار (صغير)\",\n title: \"هل أنت متأكد تمامًا؟\",\n description:\n \"لا يمكن التراجع عن هذا الإجراء. سيؤدي هذا إلى حذف حسابك نهائيًا من خوادمنا.\",\n cancel: \"إلغاء\",\n continue: \"متابعة\",\n smallTitle: \"السماح للملحق بالاتصال؟\",\n smallDescription: \"هل تريد السماح لملحق USB بالاتصال بهذا الجهاز؟\",\n dontAllow: \"عدم السماح\",\n allow: \"السماح\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n showDialog: \"הצג דיאלוג\",\n showDialogSm: \"הצג דיאלוג (קטן)\",\n title: \"האם אתה בטוח לחלוטין?\",\n description:\n \"פעולה זו לא ניתנת לביטול. זה ימחק לצמיתות את החשבון שלך מהשרתים שלנו.\",\n cancel: \"ביטול\",\n continue: \"המשך\",\n smallTitle: \"לאפשר להתקן להתחבר?\",\n smallDescription: \"האם אתה רוצה לאפשר להתקן USB להתחבר למכשיר זה?\",\n dontAllow: \"אל תאפשר\",\n allow: \"אפשר\",\n },\n },\n} as const\n\nconst language = \"ar\"\nconst { dir, values: t } = translations[language]\n---\n\n
\n \n {t.showDialog}\n \n \n {t.title}\n {t.description}\n \n \n {t.cancel}\n {t.continue}\n \n \n \n \n {t.showDialogSm}\n \n \n \n \n \n {t.smallTitle}\n {t.smallDescription}\n \n \n {t.dontAllow}\n {t.allow}\n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-small-media.astro", + "content": "---\nimport BluetoothIcon from \"@lucide/astro/icons/bluetooth\"\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\n---\n\n\n Show Dialog\n \n \n \n \n \n Allow accessory to connect?\n \n Do you want to allow the USB accessory to connect to this device?\n \n \n \n Don't allow\n Allow\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-small.astro", + "content": "---\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\n---\n\n\n Show Dialog\n \n \n Allow accessory to connect?\n \n Do you want to allow the USB accessory to connect to this device?\n \n \n \n Don't allow\n Allow\n \n \n\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/alert-dialog/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/alert-dialog.json b/public/r/alert-dialog.json index c8afa0064..a61f7b1b6 100644 --- a/public/r/alert-dialog.json +++ b/public/r/alert-dialog.json @@ -76,7 +76,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/alert-dialog/", + "docs": "https://ui.full.dev/astro/components/alert-dialog/", "categories": [ "ui" ], diff --git a/public/r/alert-examples.json b/public/r/alert-examples.json new file mode 100644 index 000000000..4fd831c0a --- /dev/null +++ b/public/r/alert-examples.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "alert-examples", + "title": "Alert examples", + "description": "The examples from the shadcn/ui Alert docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/alert", + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/examples/alert/alert-action.astro", + "content": "---\nimport {\n Alert,\n AlertAction,\n AlertDescription,\n AlertTitle,\n} from \"@/components/ui/alert\"\nimport { Button } from \"@/components/ui/button\"\n---\n\n\n Dark mode is now available\n \n Enable it under your profile settings to get started.\n \n \n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-basic.astro", + "content": "---\nimport CheckCircle2Icon from \"@lucide/astro/icons/circle-check\"\n\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\"\n---\n\n\n \n Account updated successfully\n \n Your profile information has been saved. Changes will be reflected\n immediately.\n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-colors.astro", + "content": "---\nimport AlertTriangleIcon from \"@lucide/astro/icons/triangle-alert\"\n\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\"\n---\n\n\n \n Your subscription will expire in 3 days.\n \n Renew now to avoid service interruption or upgrade to a paid plan to\n continue using the service.\n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-demo.astro", + "content": "---\nimport CheckCircle2Icon from \"@lucide/astro/icons/circle-check\"\nimport InfoIcon from \"@lucide/astro/icons/info\"\n\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\"\n---\n\n
\n \n \n Payment successful\n \n Your payment of $29.99 has been processed. A receipt has been sent to your\n email address.\n \n \n \n \n New feature available\n \n We've added dark mode support. You can enable it in your account settings.\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-destructive.astro", + "content": "---\nimport AlertCircleIcon from \"@lucide/astro/icons/circle-alert\"\n\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\"\n---\n\n\n \n Payment failed\n \n Your payment could not be processed. Please check your payment method and\n try again.\n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-rtl.astro", + "content": "---\nimport CheckCircle2Icon from \"@lucide/astro/icons/circle-check\"\nimport InfoIcon from \"@lucide/astro/icons/info\"\n\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n paymentTitle: \"Payment successful\",\n paymentDescription:\n \"Your payment of $29.99 has been processed. A receipt has been sent to your email address.\",\n featureTitle: \"New feature available\",\n featureDescription:\n \"We've added dark mode support. You can enable it in your account settings.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n paymentTitle: \"تم الدفع بنجاح\",\n paymentDescription:\n \"تمت معالجة دفعتك البالغة 29.99 دولارًا. تم إرسال إيصال إلى عنوان بريدك الإلكتروني.\",\n featureTitle: \"ميزة جديدة متاحة\",\n featureDescription:\n \"لقد أضفنا دعم الوضع الداكن. يمكنك تفعيله في إعدادات حسابك.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n paymentTitle: \"התשלום בוצע בהצלחה\",\n paymentDescription:\n \"התשלום שלך בסך 29.99 דולר עובד. קבלה נשלחה לכתובת האימייל שלך.\",\n featureTitle: \"תכונה חדשה זמינה\",\n featureDescription:\n \"הוספנו תמיכה במצב כהה. אתה יכול להפעיל אותו בהגדרות החשבון שלך.\",\n },\n },\n} as const\n\nconst alerts = [\n {\n icon: CheckCircle2Icon,\n titleKey: \"paymentTitle\",\n descriptionKey: \"paymentDescription\",\n },\n {\n icon: InfoIcon,\n titleKey: \"featureTitle\",\n descriptionKey: \"featureDescription\",\n },\n] as const\n\nconst { dir, values: t } = translations.ar\n---\n\n
\n {alerts.map((alert) => {\n const Icon = alert.icon\n return (\n \n \n {t[alert.titleKey]}\n {t[alert.descriptionKey]}\n \n )\n })}\n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/alert/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/alert.json b/public/r/alert.json index b2dfb3ac1..c15f2c60a 100644 --- a/public/r/alert.json +++ b/public/r/alert.json @@ -30,7 +30,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/alert/", + "docs": "https://ui.full.dev/astro/components/alert/", "categories": [ "ui" ], diff --git a/public/r/article-1.json b/public/r/article-1.json index a864d2860..472be6dd3 100644 --- a/public/r/article-1.json +++ b/public/r/article-1.json @@ -14,7 +14,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/article/", + "docs": "https://ui.full.dev/astro/blocks/article/", "categories": [ "article" ], diff --git a/public/r/article-2.json b/public/r/article-2.json index c0a3f5f9a..9908bc9d9 100644 --- a/public/r/article-2.json +++ b/public/r/article-2.json @@ -14,7 +14,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/article/", + "docs": "https://ui.full.dev/astro/blocks/article/", "categories": [ "article" ], diff --git a/public/r/articles-1.json b/public/r/articles-1.json index 2c9f3ed3b..3b90cbe1b 100644 --- a/public/r/articles-1.json +++ b/public/r/articles-1.json @@ -14,7 +14,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/articles/", + "docs": "https://ui.full.dev/astro/blocks/articles/", "categories": [ "articles" ], diff --git a/public/r/articles-2.json b/public/r/articles-2.json index 6e60d3f18..f844448a6 100644 --- a/public/r/articles-2.json +++ b/public/r/articles-2.json @@ -15,7 +15,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/articles/", + "docs": "https://ui.full.dev/astro/blocks/articles/", "categories": [ "articles" ], diff --git a/public/r/articles-3.json b/public/r/articles-3.json index bd0837d65..ebea57db9 100644 --- a/public/r/articles-3.json +++ b/public/r/articles-3.json @@ -14,7 +14,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/articles/", + "docs": "https://ui.full.dev/astro/blocks/articles/", "categories": [ "articles" ], diff --git a/public/r/articles-4.json b/public/r/articles-4.json index ddff63354..c425ac581 100644 --- a/public/r/articles-4.json +++ b/public/r/articles-4.json @@ -14,7 +14,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/articles/", + "docs": "https://ui.full.dev/astro/blocks/articles/", "categories": [ "articles" ], diff --git a/public/r/aspect-ratio-examples.json b/public/r/aspect-ratio-examples.json new file mode 100644 index 000000000..87eeacb8b --- /dev/null +++ b/public/r/aspect-ratio-examples.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "aspect-ratio-examples", + "title": "Aspect Ratio examples", + "description": "The examples from the shadcn/ui Aspect Ratio docs.", + "registryDependencies": [ + "@fulldev/aspect-ratio" + ], + "files": [ + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-demo.astro", + "content": "---\nimport { AspectRatio } from \"@/components/ui/aspect-ratio\"\n---\n\n\n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-portrait.astro", + "content": "---\nimport { AspectRatio } from \"@/components/ui/aspect-ratio\"\n---\n\n\n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-rtl.astro", + "content": "---\nimport { AspectRatio } from \"@/components/ui/aspect-ratio\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n caption: \"Beautiful landscape\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n caption: \"منظر طبيعي جميل\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n caption: \"נוף יפה\",\n },\n },\n} as const\n\nconst { dir, values: t } = translations.ar\n---\n\n
\n \n \n \n
\n {t.caption}\n
\n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-square.astro", + "content": "---\nimport { AspectRatio } from \"@/components/ui/aspect-ratio\"\n---\n\n\n \n\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/aspect-ratio/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/aspect-ratio.json b/public/r/aspect-ratio.json index bfdeee85b..3c69b4a74 100644 --- a/public/r/aspect-ratio.json +++ b/public/r/aspect-ratio.json @@ -15,7 +15,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/aspect-ratio/", + "docs": "https://ui.full.dev/astro/components/aspect-ratio/", "categories": [ "ui" ], diff --git a/public/r/attachment-examples.json b/public/r/attachment-examples.json new file mode 100644 index 000000000..764fbc3b4 --- /dev/null +++ b/public/r/attachment-examples.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "attachment-examples", + "title": "Attachment examples", + "description": "The examples from the shadcn/ui Attachment docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/attachment", + "@fulldev/dialog", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/attachment/attachment-demo.astro", + "content": "---\nimport FileCodeIcon from \"@lucide/astro/icons/file-code\"\nimport XIcon from \"@lucide/astro/icons/x\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentGroup,\n AttachmentMedia,\n AttachmentTitle,\n} from \"@/components/ui/attachment\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\nconst images = [\n {\n name: \"workspace.png\",\n meta: \"PNG · 820 KB\",\n src: \"https://images.unsplash.com/photo-1497366754035-f200968a6e72?w=900&auto=format&fit=crop&q=80\",\n alt: \"Workspace\",\n },\n {\n name: \"desk-reference.jpg\",\n meta: \"JPG · 1.1 MB\",\n src: \"https://images.unsplash.com/photo-1497215728101-856f4ea42174?w=900&auto=format&fit=crop&q=80\",\n alt: \"Desk\",\n },\n {\n name: \"office-reference.jpg\",\n meta: \"JPG · 940 KB\",\n src: \"https://images.unsplash.com/photo-1497366811353-6870744d04b2?w=900&auto=format&fit=crop&q=80\",\n alt: \"Office\",\n },\n]\n---\n\n
\n \n {images.map((image) => (\n \n \n {image.alt}\n \n \n {image.name}\n {image.meta}\n \n \n ))}\n \n \n \n \n \n \n sales-dashboard.pdf\n Uploading · 64%\n \n \n \n \n \n \n \n \n \n \n \n \n message-renderer.tsx\n TypeScript · 12 KB\n \n \n \n \n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-group.astro", + "content": "---\nimport FileCodeIcon from \"@lucide/astro/icons/file-code\"\nimport FileTextIcon from \"@lucide/astro/icons/file-text\"\nimport TableIcon from \"@lucide/astro/icons/table\"\nimport XIcon from \"@lucide/astro/icons/x\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentGroup,\n AttachmentMedia,\n AttachmentTitle,\n} from \"@/components/ui/attachment\"\n\ntype Item = {\n name: string\n meta: string\n icon?: typeof FileTextIcon\n src?: string\n}\n\nconst items: Item[] = [\n { name: \"briefing-notes.pdf\", meta: \"PDF · 1.4 MB\", icon: FileTextIcon },\n {\n name: \"workspace.png\",\n meta: \"PNG · 820 KB\",\n src: \"https://images.unsplash.com/photo-1497366754035-f200968a6e72?w=900&auto=format&fit=crop&q=80\",\n },\n { name: \"customers.csv\", meta: \"CSV · 18 KB\", icon: TableIcon },\n { name: \"renderer.tsx\", meta: \"TSX · 12 KB\", icon: FileCodeIcon },\n]\n---\n\n
\n \n {items.map((item) => {\n const Icon = item.icon\n\n return (\n \n {item.src ? (\n \n {item.name}\n \n ) : Icon ? (\n \n \n \n ) : null}\n \n {item.name}\n {item.meta}\n \n \n \n \n \n \n \n )\n })}\n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-image.astro", + "content": "---\nimport XIcon from \"@lucide/astro/icons/x\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentGroup,\n AttachmentMedia,\n AttachmentTitle,\n AttachmentTrigger,\n} from \"@/components/ui/attachment\"\n\nconst images = [\n {\n name: \"workspace.png\",\n meta: \"PNG · 820 KB\",\n src: \"https://images.unsplash.com/photo-1497366754035-f200968a6e72?w=900&auto=format&fit=crop&q=80\",\n alt: \"Workspace\",\n },\n {\n name: \"desk-reference.jpg\",\n meta: \"JPG · 1.1 MB\",\n src: \"https://images.unsplash.com/photo-1497215728101-856f4ea42174?w=900&auto=format&fit=crop&q=80\",\n alt: \"Desk\",\n },\n {\n name: \"office-reference.jpg\",\n meta: \"JPG · 940 KB\",\n src: \"https://images.unsplash.com/photo-1497366811353-6870744d04b2?w=900&auto=format&fit=crop&q=80\",\n alt: \"Office\",\n },\n]\n---\n\n
\n \n {images.map((image) => (\n \n \n {image.alt}\n \n \n {image.name}\n {image.meta}\n \n \n \n \n \n \n \n \n ))}\n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-sizes.astro", + "content": "---\nimport FileTextIcon from \"@lucide/astro/icons/file-text\"\n\nimport {\n Attachment,\n AttachmentContent,\n AttachmentDescription,\n AttachmentMedia,\n AttachmentTitle,\n} from \"@/components/ui/attachment\"\n---\n\n
\n \n \n \n \n \n Default attachment\n PDF · 2.4 MB\n \n \n \n \n \n \n \n Small attachment\n PDF · 2.4 MB\n \n \n \n \n \n \n \n Extra small attachment\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-states.astro", + "content": "---\nimport CheckIcon from \"@lucide/astro/icons/check\"\nimport ClockIcon from \"@lucide/astro/icons/clock\"\nimport FileWarningIcon from \"@lucide/astro/icons/file-exclamation-point\"\nimport FileTextIcon from \"@lucide/astro/icons/file-text\"\nimport RefreshCwIcon from \"@lucide/astro/icons/refresh-cw\"\nimport XIcon from \"@lucide/astro/icons/x\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentMedia,\n AttachmentTitle,\n} from \"@/components/ui/attachment\"\nimport { Spinner } from \"@/components/ui/spinner\"\n---\n\n
\n \n \n \n \n \n selected-file.pdf\n Ready to upload\n \n \n \n \n \n \n \n \n \n \n \n \n design-system.zip\n Uploading · 64%\n \n \n \n \n \n \n \n \n \n \n \n \n market-research.pdf\n Processing document\n \n \n \n \n \n \n \n \n \n \n \n \n financial-model.xlsx\n Upload failed. Try again.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n uploaded-report.pdf\n Uploaded · 1.8 MB\n \n \n \n \n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-trigger.astro", + "content": "---\nimport CopyIcon from \"@lucide/astro/icons/copy\"\nimport FileSearchIcon from \"@lucide/astro/icons/file-search\"\nimport XIcon from \"@lucide/astro/icons/x\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentMedia,\n AttachmentTitle,\n AttachmentTrigger,\n} from \"@/components/ui/attachment\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"@/components/ui/dialog\"\n---\n\n
\n \n \n \n \n \n \n research-summary.pdf\n Open preview dialog\n \n \n \n \n \n \n \n \n \n \n \n \n \n research-summary.pdf\n \n The attachment trigger fills the card and opens the dialog, while the\n actions stay independently clickable above it.\n \n \n \n \n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/attachment/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/attachment.json b/public/r/attachment.json index 77e20ccf4..c5fd585bd 100644 --- a/public/r/attachment.json +++ b/public/r/attachment.json @@ -58,7 +58,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/attachment/", + "docs": "https://ui.full.dev/astro/components/attachment/", "categories": [ "ui" ], diff --git a/public/r/avatar-examples.json b/public/r/avatar-examples.json new file mode 100644 index 000000000..d27fb2285 --- /dev/null +++ b/public/r/avatar-examples.json @@ -0,0 +1,68 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "avatar-examples", + "title": "Avatar examples", + "description": "The examples from the shadcn/ui Avatar docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/dropdown-menu" + ], + "files": [ + { + "path": "src/components/examples/avatar/avatar-badge-icon.astro", + "content": "---\nimport PlusIcon from \"@lucide/astro/icons/plus\"\n\nimport {\n Avatar,\n AvatarBadge,\n AvatarFallback,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n---\n\n\n \n PP\n \n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-badge.astro", + "content": "---\nimport {\n Avatar,\n AvatarBadge,\n AvatarFallback,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n---\n\n\n \n CN\n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-basic.astro", + "content": "---\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\n---\n\n\n \n CN\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-demo.astro", + "content": "---\nimport {\n Avatar,\n AvatarBadge,\n AvatarFallback,\n AvatarGroup,\n AvatarGroupCount,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n---\n\n
\n \n \n CN\n \n \n \n ER\n \n \n \n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n +3\n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-dropdown.astro", + "content": "---\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n---\n\n\n \n \n \n CN\n \n \n \n \n Profile\n Billing\n Settings\n \n \n \n Log out\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-group-count-icon.astro", + "content": "---\nimport PlusIcon from \"@lucide/astro/icons/plus\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarGroupCount,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n---\n\n\n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n \n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-group-count.astro", + "content": "---\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarGroupCount,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n---\n\n\n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n +3\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-group.astro", + "content": "---\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n---\n\n\n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-rtl.astro", + "content": "---\nimport {\n Avatar,\n AvatarBadge,\n AvatarFallback,\n AvatarGroup,\n AvatarGroupCount,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n moreUsers: \"+3\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n moreUsers: \"+٣\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n moreUsers: \"+3\",\n },\n },\n}\n\nconst { dir, values: t } = translations.ar\n---\n\n
\n \n \n CN\n \n \n \n ER\n \n \n \n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n {t.moreUsers}\n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-size.astro", + "content": "---\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\n---\n\n
\n \n \n CN\n \n \n \n CN\n \n \n \n CN\n \n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/avatar/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/avatar.json b/public/r/avatar.json index 7a2c68f25..39d4d637e 100644 --- a/public/r/avatar.json +++ b/public/r/avatar.json @@ -40,7 +40,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/avatar/", + "docs": "https://ui.full.dev/astro/components/avatar/", "categories": [ "ui" ], diff --git a/public/r/badge-examples.json b/public/r/badge-examples.json new file mode 100644 index 000000000..59911406b --- /dev/null +++ b/public/r/badge-examples.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "badge-examples", + "title": "Badge examples", + "description": "The examples from the shadcn/ui Badge docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/badge/badge-colors.astro", + "content": "---\nimport { Badge } from \"@/components/ui/badge\"\n---\n\n
\n \n Blue\n \n \n Green\n \n \n Sky\n \n \n Purple\n \n \n Red\n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-demo.astro", + "content": "---\nimport { Badge } from \"@/components/ui/badge\"\n---\n\n
\n Badge\n Secondary\n Destructive\n Outline\n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-icon.astro", + "content": "---\nimport BadgeCheck from \"@lucide/astro/icons/badge-check\"\nimport BookmarkIcon from \"@lucide/astro/icons/bookmark\"\n\nimport { Badge } from \"@/components/ui/badge\"\n---\n\n
\n \n \n Verified\n \n \n Bookmark\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-link.astro", + "content": "---\nimport ArrowUpRightIcon from \"@lucide/astro/icons/arrow-up-right\"\n\nimport { Badge } from \"@/components/ui/badge\"\n---\n\n\n Open Link \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-rtl.astro", + "content": "---\nimport BadgeCheck from \"@lucide/astro/icons/badge-check\"\nimport BookmarkIcon from \"@lucide/astro/icons/bookmark\"\n\nimport { Badge } from \"@/components/ui/badge\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n badge: \"Badge\",\n secondary: \"Secondary\",\n destructive: \"Destructive\",\n outline: \"Outline\",\n verified: \"Verified\",\n bookmark: \"Bookmark\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n badge: \"شارة\",\n secondary: \"ثانوي\",\n destructive: \"مدمر\",\n outline: \"مخطط\",\n verified: \"متحقق\",\n bookmark: \"إشارة مرجعية\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n badge: \"תג\",\n secondary: \"משני\",\n destructive: \"הרסני\",\n outline: \"קווי מתאר\",\n verified: \"מאומת\",\n bookmark: \"סימנייה\",\n },\n },\n}\n\nconst { dir, values: t } = translations.ar\n---\n\n
\n {t.badge}\n {t.secondary}\n {t.destructive}\n {t.outline}\n \n \n {t.verified}\n \n \n {t.bookmark}\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-spinner.astro", + "content": "---\nimport { Badge } from \"@/components/ui/badge\"\nimport { Spinner } from \"@/components/ui/spinner\"\n---\n\n
\n \n \n Deleting\n \n \n Generating\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-variants.astro", + "content": "---\nimport { Badge } from \"@/components/ui/badge\"\n---\n\n
\n Default\n Secondary\n Destructive\n Outline\n Ghost\n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/badge/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/badge.json b/public/r/badge.json index 0bb942c46..1a0ee9d59 100644 --- a/public/r/badge.json +++ b/public/r/badge.json @@ -20,7 +20,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/badge/", + "docs": "https://ui.full.dev/astro/components/badge/", "categories": [ "ui" ], diff --git a/public/r/banner-1.json b/public/r/banner-1.json index 3d0e3d2b1..219285f8a 100644 --- a/public/r/banner-1.json +++ b/public/r/banner-1.json @@ -16,7 +16,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/banner/", + "docs": "https://ui.full.dev/astro/blocks/banner/", "categories": [ "banner" ], diff --git a/public/r/banner-2.json b/public/r/banner-2.json index eb1d06077..22e7df821 100644 --- a/public/r/banner-2.json +++ b/public/r/banner-2.json @@ -14,7 +14,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/banner/", + "docs": "https://ui.full.dev/astro/blocks/banner/", "categories": [ "banner" ], diff --git a/public/r/banner.json b/public/r/banner.json index d3a8e8580..637a103f0 100644 --- a/public/r/banner.json +++ b/public/r/banner.json @@ -23,7 +23,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/banner/", + "docs": "https://ui.full.dev/astro/components/banner/", "categories": [ "ui" ], diff --git a/public/r/base.json b/public/r/base.json index 87c8c71ad..ce17be752 100644 --- a/public/r/base.json +++ b/public/r/base.json @@ -128,7 +128,7 @@ } } }, - "docs": "https://ui.full.dev/docs/installation/", + "docs": "https://ui.full.dev/astro/docs/installation/", "type": "registry:base", "config": { "style": "base-vega", diff --git a/public/r/blocks-1.json b/public/r/blocks-1.json index 8719d1a46..e12d1089b 100644 --- a/public/r/blocks-1.json +++ b/public/r/blocks-1.json @@ -19,7 +19,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/", + "docs": "https://ui.full.dev/astro/blocks/", "categories": [ "blocks" ], diff --git a/public/r/blocks.json b/public/r/blocks.json index 772ba8734..f490639fa 100644 --- a/public/r/blocks.json +++ b/public/r/blocks.json @@ -87,6 +87,6 @@ "@fulldev/services-7", "@fulldev/sidebar-1" ], - "docs": "https://ui.full.dev/blocks/", + "docs": "https://ui.full.dev/astro/blocks/", "type": "registry:item" } \ No newline at end of file diff --git a/public/r/breadcrumb-examples.json b/public/r/breadcrumb-examples.json new file mode 100644 index 000000000..da17c1f39 --- /dev/null +++ b/public/r/breadcrumb-examples.json @@ -0,0 +1,53 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "breadcrumb-examples", + "title": "Breadcrumb examples", + "description": "The examples from the shadcn/ui Breadcrumb docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/breadcrumb", + "@fulldev/button", + "@fulldev/dropdown-menu" + ], + "files": [ + { + "path": "src/components/examples/breadcrumb/breadcrumb-basic.astro", + "content": "---\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\n---\n\n\n \n \n Home\n \n \n \n Components\n \n \n \n Breadcrumb\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-demo.astro", + "content": "---\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n---\n\n\n \n \n Home\n \n \n \n \n \n \n Toggle menu\n \n \n \n Documentation\n Themes\n GitHub\n \n \n \n \n \n \n Components\n \n \n \n Breadcrumb\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-dropdown.astro", + "content": "---\nimport ChevronDownIcon from \"@lucide/astro/icons/chevron-down\"\nimport DotIcon from \"@lucide/astro/icons/dot\"\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n---\n\n\n \n \n Home\n \n \n \n \n \n \n \n Components\n \n \n \n \n Documentation\n Themes\n GitHub\n \n \n \n \n \n \n \n \n Breadcrumb\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-ellipsis.astro", + "content": "---\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\n---\n\n\n \n \n Home\n \n \n \n \n \n \n \n \n Components\n \n \n \n \n Breadcrumb\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-link.astro", + "content": "---\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\n---\n\n\n \n \n Home\n \n \n \n Components\n \n \n \n Breadcrumb\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-rtl.astro", + "content": "---\nimport ChevronDownIcon from \"@lucide/astro/icons/chevron-down\"\nimport DotIcon from \"@lucide/astro/icons/dot\"\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n home: \"Home\",\n components: \"Components\",\n documentation: \"Documentation\",\n themes: \"Themes\",\n github: \"GitHub\",\n breadcrumb: \"Breadcrumb\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n home: \"الرئيسية\",\n components: \"المكونات\",\n documentation: \"التوثيق\",\n themes: \"السمات\",\n github: \"جيت هاب\",\n breadcrumb: \"مسار التنقل\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n home: \"בית\",\n components: \"רכיבים\",\n documentation: \"תיעוד\",\n themes: \"ערכות נושא\",\n github: \"גיטהאב\",\n breadcrumb: \"פירורי לחם\",\n },\n },\n}\n\nconst language = \"ar\"\nconst { dir, values: t } = translations[language]\n---\n\n\n \n \n {t.home}\n \n \n \n \n \n \n \n {t.components}\n \n \n \n \n {t.documentation}\n {t.themes}\n {t.github}\n \n \n \n \n \n \n \n \n {t.breadcrumb}\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-separator.astro", + "content": "---\nimport DotIcon from \"@lucide/astro/icons/dot\"\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\n---\n\n\n \n \n Home\n \n \n \n \n \n Components\n \n \n \n \n \n Breadcrumb\n \n \n\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/breadcrumb/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/breadcrumb.json b/public/r/breadcrumb.json index ada28b337..3021fa2a4 100644 --- a/public/r/breadcrumb.json +++ b/public/r/breadcrumb.json @@ -48,7 +48,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/breadcrumb/", + "docs": "https://ui.full.dev/astro/components/breadcrumb/", "categories": [ "ui" ], diff --git a/public/r/button-examples.json b/public/r/button-examples.json new file mode 100644 index 000000000..caf7f6661 --- /dev/null +++ b/public/r/button-examples.json @@ -0,0 +1,87 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "button-examples", + "title": "Button examples", + "description": "The examples from the shadcn/ui Button docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/button/button-default.astro", + "content": "---\nimport { Button } from \"@/components/ui/button\"\n---\n\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-demo.astro", + "content": "---\nimport ArrowUpIcon from \"@lucide/astro/icons/arrow-up\"\n\nimport { Button } from \"@/components/ui/button\"\n---\n\n
\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-destructive.astro", + "content": "---\nimport { Button } from \"@/components/ui/button\"\n---\n\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-ghost.astro", + "content": "---\nimport { Button } from \"@/components/ui/button\"\n---\n\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-icon.astro", + "content": "---\nimport CircleFadingArrowUpIcon from \"@lucide/astro/icons/circle-fading-arrow-up\"\n\nimport { Button } from \"@/components/ui/button\"\n---\n\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-link.astro", + "content": "---\nimport { Button } from \"@/components/ui/button\"\n---\n\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-outline.astro", + "content": "---\nimport { Button } from \"@/components/ui/button\"\n---\n\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-render.astro", + "content": "---\nimport { Button } from \"@/components/ui/button\"\n---\n\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-rounded.astro", + "content": "---\nimport ArrowUpIcon from \"@lucide/astro/icons/arrow-up\"\n\nimport { Button } from \"@/components/ui/button\"\n---\n\n
\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-rtl.astro", + "content": "---\nimport ArrowRightIcon from \"@lucide/astro/icons/arrow-right\"\nimport PlusIcon from \"@lucide/astro/icons/plus\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n button: \"Button\",\n submit: \"Submit\",\n delete: \"Delete\",\n loading: \"Loading\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n button: \"زر\",\n submit: \"إرسال\",\n delete: \"حذف\",\n loading: \"جاري التحميل\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n button: \"כפתור\",\n submit: \"שלח\",\n delete: \"מחק\",\n loading: \"טוען\",\n },\n },\n}\n\nconst { dir, values: t } = translations.ar\n---\n\n
\n \n \n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-secondary.astro", + "content": "---\nimport { Button } from \"@/components/ui/button\"\n---\n\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-size.astro", + "content": "---\nimport ArrowUpRightIcon from \"@lucide/astro/icons/arrow-up-right\"\n\nimport { Button } from \"@/components/ui/button\"\n---\n\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-spinner.astro", + "content": "---\nimport { Button } from \"@/components/ui/button\"\nimport { Spinner } from \"@/components/ui/spinner\"\n---\n\n
\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-with-icon.astro", + "content": "---\nimport GitBranchIcon from \"@lucide/astro/icons/git-branch\"\nimport GitForkIcon from \"@lucide/astro/icons/git-fork\"\n\nimport { Button } from \"@/components/ui/button\"\n---\n\n
\n \n \n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/button/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/button-group-examples.json b/public/r/button-group-examples.json new file mode 100644 index 000000000..9fcf9322e --- /dev/null +++ b/public/r/button-group-examples.json @@ -0,0 +1,75 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "button-group-examples", + "title": "Button Group examples", + "description": "The examples from the shadcn/ui Button Group docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/button-group", + "@fulldev/dropdown-menu", + "@fulldev/field", + "@fulldev/input", + "@fulldev/input-group", + "@fulldev/popover", + "@fulldev/select", + "@fulldev/textarea", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/button-group/button-group-dropdown.astro", + "content": "---\nimport CheckIcon from \"@lucide/astro/icons/check\"\nimport ChevronDownIcon from \"@lucide/astro/icons/chevron-down\"\nimport CopyIcon from \"@lucide/astro/icons/copy\"\nimport ShareIcon from \"@lucide/astro/icons/share\"\nimport TrashIcon from \"@lucide/astro/icons/trash\"\nimport AlertTriangleIcon from \"@lucide/astro/icons/triangle-alert\"\nimport UserRoundXIcon from \"@lucide/astro/icons/user-round-x\"\nimport VolumeOffIcon from \"@lucide/astro/icons/volume-off\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n---\n\n\n \n \n \n \n \n \n \n \n \n Mute Conversation\n \n \n \n Mark as Read\n \n \n \n Report Conversation\n \n \n \n Block User\n \n \n \n Share Conversation\n \n \n \n Copy Conversation\n \n \n \n \n \n \n Delete Conversation\n \n \n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-input-group.astro", + "content": "---\nimport AudioLinesIcon from \"@lucide/astro/icons/audio-lines\"\nimport PlusIcon from \"@lucide/astro/icons/plus\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\n---\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n Voice Mode\n \n \n \n \n\n\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-input.astro", + "content": "---\nimport SearchIcon from \"@lucide/astro/icons/search\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport { Input } from \"@/components/ui/input\"\n---\n\n\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-nested.astro", + "content": "---\nimport AudioLinesIcon from \"@lucide/astro/icons/audio-lines\"\nimport PlusIcon from \"@lucide/astro/icons/plus\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\n---\n\n\n \n \n \n \n \n \n \n \n \n \n \n Voice Mode\n \n \n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-orientation.astro", + "content": "---\nimport MinusIcon from \"@lucide/astro/icons/minus\"\nimport PlusIcon from \"@lucide/astro/icons/plus\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\n---\n\n\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-popover.astro", + "content": "---\nimport BotIcon from \"@lucide/astro/icons/bot\"\nimport ChevronDownIcon from \"@lucide/astro/icons/chevron-down\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\nimport { Textarea } from \"@/components/ui/textarea\"\n---\n\n\n \n \n \n \n \n \n \n Start a new task with Copilot\n \n Describe your task in natural language.\n \n \n \n \n Task Description\n \n \n \n \n Submit\n \n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-demo.astro", + "content": "---\nimport SearchIcon from \"@lucide/astro/icons/search\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n---\n\n\n \n \n \n \n 12 results\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-dropdown.astro", + "content": "---\nimport ChevronDownIcon from \"@lucide/astro/icons/chevron-down\"\nimport MoreHorizontal from \"@lucide/astro/icons/ellipsis\"\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n---\n\n
\n \n \n \n \n \n \n \n \n \n Settings\n Copy path\n Open location\n \n \n \n \n \n \n \n \n \n \n Search In... \n \n \n \n Documentation\n Blog Posts\n Changelog\n \n \n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-icon.astro", + "content": "---\nimport CheckIcon from \"@lucide/astro/icons/check\"\nimport CreditCardIcon from \"@lucide/astro/icons/credit-card\"\nimport InfoIcon from \"@lucide/astro/icons/info\"\nimport MailIcon from \"@lucide/astro/icons/mail\"\nimport SearchIcon from \"@lucide/astro/icons/search\"\nimport StarIcon from \"@lucide/astro/icons/star\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n---\n\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-inline-end.astro", + "content": "---\nimport EyeOffIcon from \"@lucide/astro/icons/eye-off\"\n\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n---\n\n\n Input\n \n \n \n \n \n \n Icon positioned at the end.\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-inline-start.astro", + "content": "---\nimport SearchIcon from \"@lucide/astro/icons/search\"\n\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n---\n\n\n Input\n \n \n \n \n \n \n Icon positioned at the start.\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-kbd.astro", + "content": "---\nimport SearchIcon from \"@lucide/astro/icons/search\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport { Kbd } from \"@/components/ui/kbd\"\n---\n\n\n \n \n \n \n \n ⌘K\n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-rtl.astro", + "content": "---\nimport SearchIcon from \"@lucide/astro/icons/search\"\n\nimport {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n InputGroupText,\n InputGroupTextarea,\n} from \"@/components/ui/input-group\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n placeholder: \"Search...\",\n results: \"12 results\",\n searching: \"Searching...\",\n saving: \"Saving...\",\n savingChanges: \"Saving changes...\",\n textareaLabel: \"Textarea\",\n textareaPlaceholder: \"Write a comment...\",\n characterCount: \"0/280\",\n post: \"Post\",\n textareaDescription: \"Footer positioned below the textarea.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n placeholder: \"بحث...\",\n results: \"١٢ نتيجة\",\n searching: \"جاري البحث...\",\n saving: \"جاري الحفظ...\",\n savingChanges: \"جاري حفظ التغييرات...\",\n textareaLabel: \"منطقة النص\",\n textareaPlaceholder: \"اكتب تعليقًا...\",\n characterCount: \"٠/٢٨٠\",\n post: \"نشر\",\n textareaDescription: \"تذييل موضع أسفل منطقة النص.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n placeholder: \"חפש...\",\n results: \"12 תוצאות\",\n searching: \"מחפש...\",\n saving: \"שומר...\",\n savingChanges: \"שומר שינויים...\",\n textareaLabel: \"אזור טקסט\",\n textareaPlaceholder: \"כתוב תגובה...\",\n characterCount: \"0/280\",\n post: \"פרסם\",\n textareaDescription: \"כותרת תחתונה ממוקמת מתחת לאזור הטקסט.\",\n },\n },\n}\n\nconst { dir, values: t } = translations.ar\n---\n\n
\n \n \n \n \n \n {t.results}\n \n \n \n \n \n \n \n \n \n \n {t.saving}\n \n \n \n \n \n {t.textareaLabel}\n \n \n \n {t.characterCount}\n \n {t.post}\n \n \n \n {t.textareaDescription}\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-spinner.astro", + "content": "---\nimport LoaderIcon from \"@lucide/astro/icons/loader\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n InputGroupText,\n} from \"@/components/ui/input-group\"\nimport { Spinner } from \"@/components/ui/spinner\"\n---\n\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Saving...\n \n \n \n \n \n \n \n \n \n \n Please wait...\n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-text.astro", + "content": "---\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n InputGroupText,\n InputGroupTextarea,\n} from \"@/components/ui/input-group\"\n---\n\n
\n \n \n $\n \n \n \n USD\n \n \n \n \n https://\n \n \n \n .com\n \n \n \n \n \n @company.com\n \n \n \n \n \n \n 120 characters left\n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-textarea.astro", + "content": "---\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupText,\n InputGroupTextarea,\n} from \"@/components/ui/input-group\"\n---\n\n
\n \n \n \n Line 1, Column 1\n \n Run\n \n \n \n \n \n \n \n \n \n \n \n \n script.js\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/input-group/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/input-group.json b/public/r/input-group.json index b3fc8ff26..782bdfe7b 100644 --- a/public/r/input-group.json +++ b/public/r/input-group.json @@ -45,7 +45,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/input-group/", + "docs": "https://ui.full.dev/astro/components/input-group/", "categories": [ "ui" ], diff --git a/public/r/input.json b/public/r/input.json index 4121f5989..294bc31f6 100644 --- a/public/r/input.json +++ b/public/r/input.json @@ -15,7 +15,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/input/", + "docs": "https://ui.full.dev/astro/components/input/", "categories": [ "ui" ], diff --git a/public/r/item-examples.json b/public/r/item-examples.json new file mode 100644 index 000000000..1d1355d43 --- /dev/null +++ b/public/r/item-examples.json @@ -0,0 +1,74 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "item-examples", + "title": "Item examples", + "description": "The examples from the shadcn/ui Item docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/item" + ], + "files": [ + { + "path": "src/components/examples/item/item-avatar.astro", + "content": "---\nimport Plus from \"@lucide/astro/icons/plus\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n---\n\n
\n \n \n \n \n ER\n \n \n \n Evil Rabbit\n Last seen 5 months ago\n \n \n \n \n \n \n \n \n \n
\n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n
\n
\n \n No Team Members\n \n Invite your team to collaborate on this project.\n \n \n \n \n \n
\n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-demo.astro", + "content": "---\nimport BadgeCheckIcon from \"@lucide/astro/icons/badge-check\"\nimport ChevronRightIcon from \"@lucide/astro/icons/chevron-right\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n---\n\n
\n \n \n Basic Item\n \n A simple item with title and description.\n \n \n \n \n \n \n \n \n \n \n \n Your profile has been verified.\n \n \n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-dropdown.astro", + "content": "---\nimport ChevronDownIcon from \"@lucide/astro/icons/chevron-down\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n Item,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nconst people = [\n {\n username: \"shadcn\",\n avatar: \"https://github.com/shadcn.png\",\n email: \"shadcn@vercel.com\",\n },\n {\n username: \"maxleiter\",\n avatar: \"https://github.com/maxleiter.png\",\n email: \"maxleiter@vercel.com\",\n },\n {\n username: \"evilrabbit\",\n avatar: \"https://github.com/evilrabbit.png\",\n email: \"evilrabbit@vercel.com\",\n },\n]\n---\n\n\n \n Select \n \n \n \n {people.map((person) => (\n \n \n \n \n \n {person.username.charAt(0)}\n \n \n \n {person.username}\n \n {person.email}\n \n \n \n \n ))}\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-group.astro", + "content": "---\nimport PlusIcon from \"@lucide/astro/icons/plus\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemGroup,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nconst people = [\n {\n username: \"shadcn\",\n avatar: \"https://github.com/shadcn.png\",\n email: \"shadcn@vercel.com\",\n },\n {\n username: \"maxleiter\",\n avatar: \"https://github.com/maxleiter.png\",\n email: \"maxleiter@vercel.com\",\n },\n {\n username: \"evilrabbit\",\n avatar: \"https://github.com/evilrabbit.png\",\n email: \"evilrabbit@vercel.com\",\n },\n]\n---\n\n\n {people.map((person) => (\n \n \n \n \n {person.username.charAt(0)}\n \n \n \n {person.username}\n {person.email}\n \n \n \n \n \n ))}\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-header.astro", + "content": "---\nimport {\n Item,\n ItemContent,\n ItemDescription,\n ItemGroup,\n ItemHeader,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nconst models = [\n {\n name: \"v0-1.5-sm\",\n description: \"Everyday tasks and UI generation.\",\n image:\n \"https://images.unsplash.com/photo-1650804068570-7fb2e3dbf888?q=80&w=640&auto=format&fit=crop\",\n credit: \"Valeria Reverdo on Unsplash\",\n },\n {\n name: \"v0-1.5-lg\",\n description: \"Advanced thinking or reasoning.\",\n image:\n \"https://images.unsplash.com/photo-1610280777472-54133d004c8c?q=80&w=640&auto=format&fit=crop\",\n credit: \"Michael Oeser on Unsplash\",\n },\n {\n name: \"v0-2.0-mini\",\n description: \"Open Source model for everyone.\",\n image:\n \"https://images.unsplash.com/photo-1602146057681-08560aee8cde?q=80&w=640&auto=format&fit=crop\",\n credit: \"Cherry Laithang on Unsplash\",\n },\n]\n---\n\n
\n \n {models.map((model) => (\n \n \n \n \n \n {model.name}\n {model.description}\n \n \n ))}\n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-icon.astro", + "content": "---\nimport ShieldAlertIcon from \"@lucide/astro/icons/shield-alert\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n---\n\n
\n \n \n \n \n \n Security Alert\n New login detected from unknown device.\n \n \n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-image.astro", + "content": "---\nimport {\n Item,\n ItemContent,\n ItemDescription,\n ItemGroup,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nconst music = [\n {\n title: \"Midnight City Lights\",\n artist: \"Neon Dreams\",\n album: \"Electric Nights\",\n duration: \"3:45\",\n },\n {\n title: \"Coffee Shop Conversations\",\n artist: \"The Morning Brew\",\n album: \"Urban Stories\",\n duration: \"4:05\",\n },\n {\n title: \"Digital Rain\",\n artist: \"Cyber Symphony\",\n album: \"Binary Beats\",\n duration: \"3:30\",\n },\n]\n---\n\n
\n \n {music.map((song) => (\n \n \n \n \n \n \n {song.title} -{\" \"}\n {song.album}\n \n {song.artist}\n \n \n {song.duration}\n \n \n ))}\n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-link.astro", + "content": "---\nimport ChevronRightIcon from \"@lucide/astro/icons/chevron-right\"\nimport ExternalLinkIcon from \"@lucide/astro/icons/external-link\"\n\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemTitle,\n} from \"@/components/ui/item\"\n---\n\n
\n \n \n Visit our documentation\n \n Learn how to get started with our components.\n \n \n \n \n \n \n \n \n External resource\n \n Opens in a new tab with security attributes.\n \n \n \n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-rtl.astro", + "content": "---\nimport BadgeCheckIcon from \"@lucide/astro/icons/badge-check\"\nimport ChevronRightIcon from \"@lucide/astro/icons/chevron-right\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n basicItem: \"Basic Item\",\n basicItemDesc: \"A simple item with title and description.\",\n action: \"Action\",\n verifiedTitle: \"Your profile has been verified.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n basicItem: \"عنصر أساسي\",\n basicItemDesc: \"عنصر بسيط يحتوي على عنوان ووصف.\",\n action: \"إجراء\",\n verifiedTitle: \"تم التحقق من ملفك الشخصي.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n basicItem: \"פריט בסיסי\",\n basicItemDesc: \"פריט פשוט עם כותרת ותיאור.\",\n action: \"פעולה\",\n verifiedTitle: \"הפרופיל שלך אומת.\",\n },\n },\n} as const\n\nconst { dir, values: t } = translations.ar\n---\n\n
\n \n \n {t.basicItem}\n {t.basicItemDesc}\n \n \n \n \n \n \n \n \n \n \n {t.verifiedTitle}\n \n \n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-size.astro", + "content": "---\nimport InboxIcon from \"@lucide/astro/icons/inbox\"\n\nimport {\n Item,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n---\n\n
\n \n \n \n \n \n Default Size\n The standard size for most use cases.\n \n \n \n \n \n \n \n Small Size\n A compact size for dense layouts.\n \n \n \n \n \n \n \n Extra Small Size\n The most compact size available.\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-variant.astro", + "content": "---\nimport InboxIcon from \"@lucide/astro/icons/inbox\"\n\nimport {\n Item,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n---\n\n
\n \n \n \n \n \n Default Variant\n Transparent background with no border.\n \n \n \n \n \n \n \n Outline Variant\n Outlined style with a visible border.\n \n \n \n \n \n \n \n Muted Variant\n Muted background for secondary content.\n \n \n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/item/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/item.json b/public/r/item.json index 783d228e5..5920bbbe9 100644 --- a/public/r/item.json +++ b/public/r/item.json @@ -63,7 +63,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/item/", + "docs": "https://ui.full.dev/astro/components/item/", "categories": [ "ui" ], diff --git a/public/r/kbd-examples.json b/public/r/kbd-examples.json new file mode 100644 index 000000000..057b124f9 --- /dev/null +++ b/public/r/kbd-examples.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "kbd-examples", + "title": "Kbd examples", + "description": "The examples from the shadcn/ui Kbd docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/button-group", + "@fulldev/input-group", + "@fulldev/kbd", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/kbd/kbd-button.astro", + "content": "---\nimport { Button } from \"@/components/ui/button\"\nimport { Kbd } from \"@/components/ui/kbd\"\n---\n\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-demo.astro", + "content": "---\nimport { Kbd, KbdGroup } from \"@/components/ui/kbd\"\n---\n\n
\n \n ⌘\n ⇧\n ⌥\n ⌃\n \n \n Ctrl\n +\n B\n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-group.astro", + "content": "---\nimport { Kbd, KbdGroup } from \"@/components/ui/kbd\"\n---\n\n
\n
\n Use\n \n Ctrl + B\n Ctrl + K\n \n to open the command palette\n
\n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-input-group.astro", + "content": "---\nimport SearchIcon from \"@lucide/astro/icons/search\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport { Kbd } from \"@/components/ui/kbd\"\n---\n\n
\n \n \n \n \n \n \n ⌘\n K\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-rtl.astro", + "content": "---\nimport { Kbd, KbdGroup } from \"@/components/ui/kbd\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {},\n },\n ar: {\n dir: \"rtl\",\n values: {},\n },\n he: {\n dir: \"rtl\",\n values: {},\n },\n} as const\n\nconst { dir } = translations.ar\n---\n\n
\n \n ⌘\n ⇧\n ⌥\n ⌃\n \n \n Ctrl\n +\n B\n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-tooltip.astro", + "content": "---\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport { Kbd, KbdGroup } from \"@/components/ui/kbd\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\n---\n\n
\n \n \n \n Save\n \n \n Save Changes S\n \n \n \n \n Print\n \n \n Print Document\n \n Ctrl\n P\n \n \n \n \n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/kbd/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/kbd.json b/public/r/kbd.json index 42619bd22..16a5a08da 100644 --- a/public/r/kbd.json +++ b/public/r/kbd.json @@ -20,7 +20,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/kbd/", + "docs": "https://ui.full.dev/astro/components/kbd/", "categories": [ "ui" ], diff --git a/public/r/label-examples.json b/public/r/label-examples.json new file mode 100644 index 000000000..81f596ef4 --- /dev/null +++ b/public/r/label-examples.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "label-examples", + "title": "Label examples", + "description": "The examples from the shadcn/ui Label docs.", + "registryDependencies": [ + "@fulldev/checkbox", + "@fulldev/label" + ], + "files": [ + { + "path": "src/components/examples/label/label-demo.astro", + "content": "---\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport { Label } from \"@/components/ui/label\"\n---\n\n
\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/label/label-rtl.astro", + "content": "---\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport { Label } from \"@/components/ui/label\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n label: \"Accept terms and conditions\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n label: \"قبول الشروط والأحكام\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n label: \"קבל תנאים והגבלות\",\n },\n },\n} as const\n\nconst { dir, values: t } = translations.ar\n---\n\n
\n \n \n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/label/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/label.json b/public/r/label.json index 7537ca9ba..9348793ce 100644 --- a/public/r/label.json +++ b/public/r/label.json @@ -15,7 +15,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/label/", + "docs": "https://ui.full.dev/astro/components/label/", "categories": [ "ui" ], diff --git a/public/r/layout.json b/public/r/layout.json index dc22c1d3f..763d36281 100644 --- a/public/r/layout.json +++ b/public/r/layout.json @@ -33,7 +33,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/layout/", + "docs": "https://ui.full.dev/astro/components/layout/", "categories": [ "ui" ], diff --git a/public/r/links-2.json b/public/r/links-2.json index ed6e31559..a35111855 100644 --- a/public/r/links-2.json +++ b/public/r/links-2.json @@ -16,7 +16,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/links/", + "docs": "https://ui.full.dev/astro/blocks/links/", "categories": [ "links" ], diff --git a/public/r/logo.json b/public/r/logo.json index 56ae30c0b..5d1db0c3a 100644 --- a/public/r/logo.json +++ b/public/r/logo.json @@ -25,7 +25,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/logo/", + "docs": "https://ui.full.dev/astro/components/logo/", "categories": [ "ui" ], diff --git a/public/r/logos-1.json b/public/r/logos-1.json index de62b4b00..8218788c0 100644 --- a/public/r/logos-1.json +++ b/public/r/logos-1.json @@ -14,7 +14,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/logos/", + "docs": "https://ui.full.dev/astro/blocks/logos/", "categories": [ "logos" ], diff --git a/public/r/logos-2.json b/public/r/logos-2.json index 48760e394..d8effd0a9 100644 --- a/public/r/logos-2.json +++ b/public/r/logos-2.json @@ -15,7 +15,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/logos/", + "docs": "https://ui.full.dev/astro/blocks/logos/", "categories": [ "logos" ], diff --git a/public/r/logos-3.json b/public/r/logos-3.json index 4824f14cc..ca0442bf6 100644 --- a/public/r/logos-3.json +++ b/public/r/logos-3.json @@ -14,7 +14,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/logos/", + "docs": "https://ui.full.dev/astro/blocks/logos/", "categories": [ "logos" ], diff --git a/public/r/marquee.json b/public/r/marquee.json index 81916aedd..1d5eb6115 100644 --- a/public/r/marquee.json +++ b/public/r/marquee.json @@ -38,7 +38,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/marquee/", + "docs": "https://ui.full.dev/astro/components/marquee/", "categories": [ "ui" ], diff --git a/public/r/native-select-examples.json b/public/r/native-select-examples.json new file mode 100644 index 000000000..25e0e9285 --- /dev/null +++ b/public/r/native-select-examples.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "native-select-examples", + "title": "Native Select examples", + "description": "The examples from the shadcn/ui Native Select docs.", + "registryDependencies": [ + "@fulldev/native-select" + ], + "files": [ + { + "path": "src/components/examples/native-select/native-select-demo.astro", + "content": "---\nimport { NativeSelect, NativeSelectOption } from \"@/components/ui/native-select\"\n---\n\n\n Select status\n Todo\n In Progress\n Done\n Cancelled\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-disabled.astro", + "content": "---\nimport { NativeSelect, NativeSelectOption } from \"@/components/ui/native-select\"\n---\n\n\n Disabled\n Apple\n Banana\n Blueberry\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-groups.astro", + "content": "---\nimport {\n NativeSelect,\n NativeSelectOptGroup,\n NativeSelectOption,\n} from \"@/components/ui/native-select\"\n---\n\n\n Select department\n \n Frontend\n Backend\n DevOps\n \n \n Sales Rep\n \n Account Manager\n \n \n Sales Director\n \n \n \n Customer Support\n \n Product Manager\n \n \n Operations Manager\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-invalid.astro", + "content": "---\nimport { NativeSelect, NativeSelectOption } from \"@/components/ui/native-select\"\n---\n\n\n Error state\n Apple\n Banana\n Blueberry\n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-rtl.astro", + "content": "---\nimport { NativeSelect, NativeSelectOption } from \"@/components/ui/native-select\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n placeholder: \"Select status\",\n todo: \"Todo\",\n inProgress: \"In Progress\",\n done: \"Done\",\n cancelled: \"Cancelled\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n placeholder: \"اختر الحالة\",\n todo: \"مهام\",\n inProgress: \"قيد التنفيذ\",\n done: \"منجز\",\n cancelled: \"ملغي\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n placeholder: \"בחר סטטוס\",\n todo: \"לעשות\",\n inProgress: \"בתהליך\",\n done: \"הושלם\",\n cancelled: \"בוטל\",\n },\n },\n}\n\nconst { dir, values: t } = translations.ar\n---\n\n\n {t.placeholder}\n {t.todo}\n {t.inProgress}\n {t.done}\n {t.cancelled}\n\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/native-select/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/native-select.json b/public/r/native-select.json index bc9239ff0..9ab77e979 100644 --- a/public/r/native-select.json +++ b/public/r/native-select.json @@ -28,7 +28,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/native-select/", + "docs": "https://ui.full.dev/astro/components/native-select/", "categories": [ "ui" ], diff --git a/public/r/navigation-menu-examples.json b/public/r/navigation-menu-examples.json new file mode 100644 index 000000000..6d86d7f87 --- /dev/null +++ b/public/r/navigation-menu-examples.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "navigation-menu-examples", + "title": "Navigation Menu examples", + "description": "The examples from the shadcn/ui Navigation Menu docs.", + "dependencies": [ + "@lucide/astro" + ], + "registryDependencies": [ + "@fulldev/navigation-menu" + ], + "files": [ + { + "path": "src/components/examples/navigation-menu/navigation-menu-demo.astro", + "content": "---\nimport CircleAlertIcon from \"@lucide/astro/icons/circle-alert\"\nimport CircleCheckIcon from \"@lucide/astro/icons/circle-check\"\nimport CircleDashedIcon from \"@lucide/astro/icons/circle-dashed\"\n\nimport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n} from \"@/components/ui/navigation-menu\"\n\nconst gettingStarted = [\n {\n title: \"Introduction\",\n href: \"/docs\",\n description: \"Re-usable components built with Tailwind CSS.\",\n },\n {\n title: \"Installation\",\n href: \"/docs/installation\",\n description: \"How to install dependencies and structure your app.\",\n },\n {\n title: \"Typography\",\n href: \"https://ui.shadcn.com/docs/typeset\",\n description: \"Styles for headings, paragraphs, lists...etc\",\n },\n]\n\nconst components: { title: string; href: string; description: string }[] = [\n {\n title: \"Alert Dialog\",\n href: \"https://ui.shadcn.com/docs/components/base/alert-dialog\",\n description:\n \"A modal dialog that interrupts the user with important content and expects a response.\",\n },\n {\n title: \"Hover Card\",\n href: \"https://ui.shadcn.com/docs/components/base/hover-card\",\n description:\n \"For sighted users to preview content available behind a link.\",\n },\n {\n title: \"Progress\",\n href: \"https://ui.shadcn.com/docs/components/base/progress\",\n description:\n \"Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.\",\n },\n {\n title: \"Scroll-area\",\n href: \"https://ui.shadcn.com/docs/components/base/scroll-area\",\n description: \"Visually or semantically separates content.\",\n },\n {\n title: \"Tabs\",\n href: \"https://ui.shadcn.com/docs/components/base/tabs\",\n description:\n \"A set of layered sections of content, known as tab panels, that are displayed one at a time.\",\n },\n {\n title: \"Tooltip\",\n href: \"https://ui.shadcn.com/docs/components/base/tooltip\",\n description:\n \"A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.\",\n },\n]\n---\n\n\n \n \n Getting started\n \n
    \n {gettingStarted.map((item) => (\n
  • \n \n
    \n
    {item.title}
    \n
    \n {item.description}\n
    \n
    \n
    \n
  • \n ))}\n
\n
\n
\n \n Components\n \n
    \n {components.map((component) => (\n
  • \n \n
    \n
    {component.title}
    \n
    \n {component.description}\n
    \n
    \n
    \n
  • \n ))}\n
\n
\n
\n \n With Icon\n \n
    \n
  • \n \n \n Backlog\n \n \n \n To Do\n \n \n \n Done\n \n
  • \n
\n
\n
\n \n \n Docs\n \n \n
\n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/navigation-menu/navigation-menu-rtl.astro", + "content": "---\nimport CircleAlertIcon from \"@lucide/astro/icons/circle-alert\"\nimport CircleCheckIcon from \"@lucide/astro/icons/circle-check\"\nimport CircleDashedIcon from \"@lucide/astro/icons/circle-dashed\"\n\nimport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n} from \"@/components/ui/navigation-menu\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n gettingStarted: \"Getting started\",\n introduction: \"Introduction\",\n introductionDesc: \"Re-usable components built with Tailwind CSS.\",\n installation: \"Installation\",\n installationDesc: \"How to install dependencies and structure your app.\",\n typography: \"Typography\",\n typographyDesc: \"Styles for headings, paragraphs, lists...etc\",\n components: \"Components\",\n alertDialog: \"Alert Dialog\",\n alertDialogDesc:\n \"A modal dialog that interrupts the user with important content and expects a response.\",\n hoverCard: \"Hover Card\",\n hoverCardDesc:\n \"For sighted users to preview content available behind a link.\",\n progress: \"Progress\",\n progressDesc:\n \"Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.\",\n scrollArea: \"Scroll-area\",\n scrollAreaDesc: \"Visually or semantically separates content.\",\n tabs: \"Tabs\",\n tabsDesc:\n \"A set of layered sections of content, known as tab panels, that are displayed one at a time.\",\n tooltip: \"Tooltip\",\n tooltipDesc:\n \"A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.\",\n withIcon: \"With Icon\",\n backlog: \"Backlog\",\n toDo: \"To Do\",\n done: \"Done\",\n docs: \"Docs\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n gettingStarted: \"البدء\",\n introduction: \"مقدمة\",\n introductionDesc:\n \"مكونات قابلة لإعادة الاستخدام مبنية باستخدام Tailwind CSS.\",\n installation: \"التثبيت\",\n installationDesc: \"كيفية تثبيت التبعيات وتنظيم تطبيقك.\",\n typography: \"الطباعة\",\n typographyDesc: \"أنماط للعناوين والفقرات والقوائم...إلخ\",\n components: \"المكونات\",\n alertDialog: \"حوار التنبيه\",\n alertDialogDesc: \"حوار نافذة يقطع المستخدم بمحتوى مهم ويتوقع استجابة.\",\n hoverCard: \"بطاقة التحويم\",\n hoverCardDesc: \"للمستخدمين المبصرين لمعاينة المحتوى المتاح خلف الرابط.\",\n progress: \"التقدم\",\n progressDesc:\n \"يعرض مؤشرًا يوضح تقدم إتمام المهمة، عادةً يتم عرضه كشريط تقدم.\",\n scrollArea: \"منطقة التمرير\",\n scrollAreaDesc: \"يفصل المحتوى بصريًا أو دلاليًا.\",\n tabs: \"التبويبات\",\n tabsDesc:\n \"مجموعة من أقسام المحتوى المتعددة الطبقات، المعروفة بألواح التبويب، التي يتم عرضها واحدة في كل مرة.\",\n tooltip: \"تلميح\",\n tooltipDesc:\n \"نافذة منبثقة تعرض معلومات متعلقة بعنصر عندما يتلقى العنصر التركيز على لوحة المفاتيح أو عند تحويم الماوس فوقه.\",\n withIcon: \"مع أيقونة\",\n backlog: \"قائمة الانتظار\",\n toDo: \"المهام\",\n done: \"منجز\",\n docs: \"الوثائق\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n gettingStarted: \"התחלה\",\n introduction: \"הקדמה\",\n introductionDesc: \"רכיבים לשימוש חוזר שנבנו עם Tailwind CSS.\",\n installation: \"התקנה\",\n installationDesc: \"כיצד להתקין תלויות ולבנות את האפליקציה שלך.\",\n typography: \"טיפוגרפיה\",\n typographyDesc: \"סגנונות לכותרות, פסקאות, רשימות...וכו'\",\n components: \"רכיבים\",\n alertDialog: \"דיאלוג התראה\",\n alertDialogDesc: \"דיאלוג מודאלי שמפריע למשתמש עם תוכן חשוב ומצפה לתגובה.\",\n hoverCard: \"כרטיס ריחוף\",\n hoverCardDesc:\n \"למשתמשים רואים כדי להציג תצוגה מקדימה של תוכן זמין מאחורי קישור.\",\n progress: \"התקדמות\",\n progressDesc:\n \"מציג אינדיקטור המציג את התקדמות ההשלמה של משימה, בדרך כלל מוצג כסרגל התקדמות.\",\n scrollArea: \"אזור גלילה\",\n scrollAreaDesc: \"מפריד תוכן חזותית או סמנטית.\",\n tabs: \"כרטיסיות\",\n tabsDesc:\n \"קבוצה של חלקי תוכן מרובדים, המכונים לוחות כרטיסיות, המוצגים אחד בכל פעם.\",\n tooltip: \"טולטיפ\",\n tooltipDesc:\n \"חלון קופץ המציג מידע הקשור לאלמנט כאשר האלמנט מקבל מיקוד מקלדת או כאשר העכבר מרחף מעליו.\",\n withIcon: \"עם אייקון\",\n backlog: \"רשימת המתנה\",\n toDo: \"לעשות\",\n done: \"הושלם\",\n docs: \"תיעוד\",\n },\n },\n} as const\n\nconst components = [\n {\n titleKey: \"alertDialog\",\n descriptionKey: \"alertDialogDesc\",\n href: \"https://ui.shadcn.com/docs/components/base/alert-dialog\",\n },\n {\n titleKey: \"hoverCard\",\n descriptionKey: \"hoverCardDesc\",\n href: \"https://ui.shadcn.com/docs/components/base/hover-card\",\n },\n {\n titleKey: \"progress\",\n descriptionKey: \"progressDesc\",\n href: \"https://ui.shadcn.com/docs/components/base/progress\",\n },\n {\n titleKey: \"scrollArea\",\n descriptionKey: \"scrollAreaDesc\",\n href: \"https://ui.shadcn.com/docs/components/base/scroll-area\",\n },\n {\n titleKey: \"tabs\",\n descriptionKey: \"tabsDesc\",\n href: \"https://ui.shadcn.com/docs/components/base/tabs\",\n },\n {\n titleKey: \"tooltip\",\n descriptionKey: \"tooltipDesc\",\n href: \"https://ui.shadcn.com/docs/components/base/tooltip\",\n },\n] as const\n\nconst language = \"ar\"\nconst { dir, values: t } = translations[language]\n\nconst gettingStarted = [\n { title: t.introduction, href: \"/docs\", description: t.introductionDesc },\n {\n title: t.installation,\n href: \"/docs/installation\",\n description: t.installationDesc,\n },\n {\n title: t.typography,\n href: \"https://ui.shadcn.com/docs/typeset\",\n description: t.typographyDesc,\n },\n]\n---\n\n\n \n \n {t.gettingStarted}\n \n
    \n {gettingStarted.map((item) => (\n
  • \n \n
    \n
    {item.title}
    \n
    \n {item.description}\n
    \n
    \n
    \n
  • \n ))}\n
\n \n
\n \n {t.components}\n \n
    \n {components.map((component) => (\n
  • \n \n
    \n
    \n {t[component.titleKey]}\n
    \n
    \n {t[component.descriptionKey]}\n
    \n
    \n
    \n
  • \n ))}\n
\n \n
\n \n {t.withIcon}\n \n
    \n
  • \n \n \n {t.backlog}\n \n \n \n {t.toDo}\n \n \n \n {t.done}\n \n
  • \n
\n \n
\n \n \n {t.docs}\n \n \n
\n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/navigation-menu/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/navigation-menu.json b/public/r/navigation-menu.json index 5e76cdea7..460bd662d 100644 --- a/public/r/navigation-menu.json +++ b/public/r/navigation-menu.json @@ -59,7 +59,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/navigation-menu/", + "docs": "https://ui.full.dev/astro/components/navigation-menu/", "categories": [ "ui" ], diff --git a/public/r/pagination-examples.json b/public/r/pagination-examples.json new file mode 100644 index 000000000..a0ae7e971 --- /dev/null +++ b/public/r/pagination-examples.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "pagination-examples", + "title": "Pagination examples", + "description": "The examples from the shadcn/ui Pagination docs.", + "registryDependencies": [ + "@fulldev/field", + "@fulldev/pagination", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/pagination/pagination-demo.astro", + "content": "---\nimport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n} from \"@/components/ui/pagination\"\n---\n\n\n \n \n \n \n \n 1\n \n \n \n 2\n \n \n \n 3\n \n \n \n \n \n \n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/pagination/pagination-icons-only.astro", + "content": "---\nimport { Field, FieldLabel } from \"@/components/ui/field\"\nimport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationNext,\n PaginationPrevious,\n} from \"@/components/ui/pagination\"\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n---\n\n
\n \n Rows per page\n \n \n \n \n \n \n \n \n \n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/pagination/pagination-rtl.astro", + "content": "---\nimport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n} from \"@/components/ui/pagination\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n previous: \"Previous\",\n next: \"Next\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n previous: \"السابق\",\n next: \"التالي\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n previous: \"הקודם\",\n next: \"הבא\",\n },\n },\n} as const\n\nfunction toArabicNumerals(num: number): string {\n const arabicNumerals = [\"٠\", \"١\", \"٢\", \"٣\", \"٤\", \"٥\", \"٦\", \"٧\", \"٨\", \"٩\"]\n return num\n .toString()\n .split(\"\")\n .map((digit) => arabicNumerals[parseInt(digit, 10)])\n .join(\"\")\n}\n\nconst language: keyof typeof translations = \"ar\"\nconst { dir, values: t } = translations[language]\n\nconst formatNumber = (num: number): string => {\n if (language === \"ar\") {\n return toArabicNumerals(num)\n }\n return num.toString()\n}\n---\n\n\n \n \n \n \n \n {formatNumber(1)}\n \n \n \n {formatNumber(2)}\n \n \n \n {formatNumber(3)}\n \n \n \n \n \n \n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/pagination/pagination-simple.astro", + "content": "---\nimport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n} from \"@/components/ui/pagination\"\n---\n\n\n \n \n 1\n \n \n \n 2\n \n \n \n 3\n \n \n 4\n \n \n 5\n \n \n\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/pagination/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/pagination.json b/public/r/pagination.json index f9f0c0bae..1c58ae23f 100644 --- a/public/r/pagination.json +++ b/public/r/pagination.json @@ -51,7 +51,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/pagination/", + "docs": "https://ui.full.dev/astro/components/pagination/", "categories": [ "ui" ], diff --git a/public/r/popover-examples.json b/public/r/popover-examples.json new file mode 100644 index 000000000..c9c8972b7 --- /dev/null +++ b/public/r/popover-examples.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "popover-examples", + "title": "Popover examples", + "description": "The examples from the shadcn/ui Popover docs.", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/field", + "@fulldev/input", + "@fulldev/label", + "@fulldev/popover" + ], + "files": [ + { + "path": "src/components/examples/popover/popover-alignments.astro", + "content": "---\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n---\n\n
\n \n \n Start\n \n \n Aligned to start\n \n \n \n \n Center\n \n \n Aligned to center\n \n \n \n \n End\n \n \n Aligned to end\n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-basic.astro", + "content": "---\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n---\n\n\n \n Open Popover\n \n \n \n Dimensions\n Set the dimensions for the layer.\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-demo.astro", + "content": "---\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport { Label } from \"@/components/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n---\n\n\n \n Open popover\n \n \n
\n
\n

Dimensions

\n

\n Set the dimensions for the layer.\n

\n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n
\n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-form.astro", + "content": "---\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n---\n\n\n \n Open Popover\n \n \n \n Dimensions\n Set the dimensions for the layer.\n \n \n \n \n Width\n \n \n \n \n \n Height\n \n \n \n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-rtl.astro", + "content": "---\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n title: \"Dimensions\",\n description: \"Set the dimensions for the layer.\",\n \"inline-start\": \"Inline Start\",\n left: \"Left\",\n top: \"Top\",\n bottom: \"Bottom\",\n right: \"Right\",\n \"inline-end\": \"Inline End\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n title: \"الأبعاد\",\n description: \"تعيين الأبعاد للطبقة.\",\n \"inline-start\": \"بداية السطر\",\n left: \"يسار\",\n top: \"أعلى\",\n bottom: \"أسفل\",\n right: \"يمين\",\n \"inline-end\": \"نهاية السطر\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n title: \"מימדים\",\n description: \"הגדר את המימדים לשכבה.\",\n \"inline-start\": \"תחילת השורה\",\n left: \"שמאל\",\n top: \"למעלה\",\n bottom: \"למטה\",\n right: \"ימין\",\n \"inline-end\": \"סוף השורה\",\n },\n },\n}\n\nconst physicalSides = [\"left\", \"top\", \"bottom\", \"right\"] as const\nconst logicalSides = [\"inline-start\", \"inline-end\"] as const\n\nconst { dir, values: t } = translations.ar\n\n// PopoverContent takes physical sides, so resolve the logical ones for `dir`.\nconst resolvedSides = {\n \"inline-start\": dir === \"rtl\" ? \"right\" : \"left\",\n \"inline-end\": dir === \"rtl\" ? \"left\" : \"right\",\n} as const\n---\n\n
\n
\n {physicalSides.map((side) => (\n \n \n {t[side]}\n \n \n \n {t.title}\n {t.description}\n \n \n \n ))}\n
\n
\n {logicalSides.map((side) => (\n \n \n {t[side]}\n \n \n \n {t.title}\n {t.description}\n \n \n \n ))}\n
\n
\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/popover/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/popover.json b/public/r/popover.json index 20520698b..7d0b8ab1a 100644 --- a/public/r/popover.json +++ b/public/r/popover.json @@ -43,7 +43,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/popover/", + "docs": "https://ui.full.dev/astro/components/popover/", "categories": [ "ui" ], diff --git a/public/r/price.json b/public/r/price.json index e512209cd..d25f33123 100644 --- a/public/r/price.json +++ b/public/r/price.json @@ -30,7 +30,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/price/", + "docs": "https://ui.full.dev/astro/components/price/", "categories": [ "ui" ], diff --git a/public/r/pricing-1.json b/public/r/pricing-1.json index 2649f08fb..ed28694db 100644 --- a/public/r/pricing-1.json +++ b/public/r/pricing-1.json @@ -21,7 +21,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/pricing/", + "docs": "https://ui.full.dev/astro/blocks/pricing/", "categories": [ "pricing" ], diff --git a/public/r/pricing-2.json b/public/r/pricing-2.json index 14d7ffde3..ef75ac6d5 100644 --- a/public/r/pricing-2.json +++ b/public/r/pricing-2.json @@ -20,7 +20,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/pricing/", + "docs": "https://ui.full.dev/astro/blocks/pricing/", "categories": [ "pricing" ], diff --git a/public/r/pricing-3.json b/public/r/pricing-3.json index 5e767ea90..8770f0517 100644 --- a/public/r/pricing-3.json +++ b/public/r/pricing-3.json @@ -21,7 +21,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/pricing/", + "docs": "https://ui.full.dev/astro/blocks/pricing/", "categories": [ "pricing" ], diff --git a/public/r/product-1.json b/public/r/product-1.json index d09a7114b..d27707ec9 100644 --- a/public/r/product-1.json +++ b/public/r/product-1.json @@ -16,7 +16,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/product/", + "docs": "https://ui.full.dev/astro/blocks/product/", "categories": [ "product" ], diff --git a/public/r/products-1.json b/public/r/products-1.json index 2bc2c4508..3aaefb88e 100644 --- a/public/r/products-1.json +++ b/public/r/products-1.json @@ -16,7 +16,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/products/", + "docs": "https://ui.full.dev/astro/blocks/products/", "categories": [ "products" ], diff --git a/public/r/products-2.json b/public/r/products-2.json index 34a441afd..65776b5d6 100644 --- a/public/r/products-2.json +++ b/public/r/products-2.json @@ -16,7 +16,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/products/", + "docs": "https://ui.full.dev/astro/blocks/products/", "categories": [ "products" ], diff --git a/public/r/products-3.json b/public/r/products-3.json index 0e6645c63..e66916304 100644 --- a/public/r/products-3.json +++ b/public/r/products-3.json @@ -16,7 +16,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/products/", + "docs": "https://ui.full.dev/astro/blocks/products/", "categories": [ "products" ], diff --git a/public/r/products-4.json b/public/r/products-4.json index 6885edb3d..c32a1b0ca 100644 --- a/public/r/products-4.json +++ b/public/r/products-4.json @@ -16,7 +16,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/products/", + "docs": "https://ui.full.dev/astro/blocks/products/", "categories": [ "products" ], diff --git a/public/r/products-5.json b/public/r/products-5.json index 9b0a09fb9..2acc7e17b 100644 --- a/public/r/products-5.json +++ b/public/r/products-5.json @@ -17,7 +17,7 @@ "type": "registry:block" } ], - "docs": "https://ui.full.dev/blocks/products/", + "docs": "https://ui.full.dev/astro/blocks/products/", "categories": [ "products" ], diff --git a/public/r/radio-group-examples.json b/public/r/radio-group-examples.json new file mode 100644 index 000000000..7cfb90b31 --- /dev/null +++ b/public/r/radio-group-examples.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "radio-group-examples", + "title": "Radio Group examples", + "description": "The examples from the shadcn/ui Radio Group docs.", + "registryDependencies": [ + "@fulldev/field", + "@fulldev/label", + "@fulldev/radio-group" + ], + "files": [ + { + "path": "src/components/examples/radio-group/radio-group-choice-card.astro", + "content": "---\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldLabel,\n FieldTitle,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n---\n\n\n \n \n \n Plus\n \n For individuals and small teams.\n \n \n \n \n \n \n \n \n Pro\n For growing businesses.\n \n \n \n \n \n \n \n Enterprise\n \n For large teams and enterprises.\n \n \n \n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-demo.astro", + "content": "---\nimport { Label } from \"@/components/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n---\n\n\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-description.astro", + "content": "---\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n---\n\n\n \n \n \n Default\n Standard spacing for most use cases.\n \n \n \n \n \n Comfortable\n More space between elements.\n \n \n \n \n \n Compact\n Minimal spacing for dense layouts.\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-disabled.astro", + "content": "---\nimport { Field, FieldLabel } from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n---\n\n\n \n \n \n Disabled\n \n \n \n \n \n Option 2\n \n \n \n \n \n Option 3\n \n \n\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-fieldset.astro", + "content": "---\nimport {\n Field,\n FieldDescription,\n FieldLabel,\n FieldLegend,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n---\n\n
\n Subscription Plan\n \n Yearly and lifetime plans offer significant savings.\n \n \n \n \n \n Monthly ($9.99/month)\n \n \n \n \n \n Yearly ($99.99/year)\n \n \n \n \n \n Lifetime ($299.99)\n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-invalid.astro", + "content": "---\nimport {\n Field,\n FieldDescription,\n FieldLabel,\n FieldLegend,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n---\n\n
\n Notification Preferences\n \n Choose how you want to receive notifications.\n \n \n \n \n \n Email only\n \n \n \n \n \n SMS only\n \n \n \n \n \n Both Email & SMS\n \n \n \n
\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-rtl.astro", + "content": "---\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n\nconst translations = {\n en: {\n dir: \"ltr\",\n values: {\n default: \"Default\",\n defaultDescription: \"Standard spacing for most use cases.\",\n comfortable: \"Comfortable\",\n comfortableDescription: \"More space between elements.\",\n compact: \"Compact\",\n compactDescription: \"Minimal spacing for dense layouts.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n default: \"افتراضي\",\n defaultDescription: \"تباعد قياسي لمعظم حالات الاستخدام.\",\n comfortable: \"مريح\",\n comfortableDescription: \"مساحة أكبر بين العناصر.\",\n compact: \"مضغوط\",\n compactDescription: \"تباعد أدنى للتخطيطات الكثيفة.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n default: \"ברירת מחדל\",\n defaultDescription: \"ריווח סטנדרטי לרוב מקרי השימוש.\",\n comfortable: \"נוח\",\n comfortableDescription: \"יותר מקום בין האלמנטים.\",\n compact: \"קומפקטי\",\n compactDescription: \"ריווח מינימלי לפריסות צפופות.\",\n },\n },\n}\n\nconst { dir, values: t } = translations.ar\n---\n\n\n \n \n \n \n {t.default}\n \n {t.defaultDescription}\n \n \n \n \n \n \n {t.comfortable}\n \n {t.comfortableDescription}\n \n \n \n \n \n \n {t.compact}\n \n {t.compactDescription}\n \n \n\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/astro/components/radio-group/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/radio-group.json b/public/r/radio-group.json index 7873dbd1a..53c1ffb7f 100644 --- a/public/r/radio-group.json +++ b/public/r/radio-group.json @@ -14,7 +14,7 @@ }, { "path": "src/components/ui/radio-group/radio-group-item.astro", - "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"span\"> & {\n value: string\n disabled?: boolean\n indicatorClass?: string\n}\n\nconst {\n class: className,\n value,\n disabled,\n indicatorClass,\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<\"button\"> & {\n value: string\n disabled?: boolean\n indicatorClass?: string\n}\n\nconst {\n class: className,\n value,\n disabled,\n indicatorClass,\n ...props\n} = Astro.props\n---\n\n\n \n \n \n\n", "type": "registry:ui" }, { @@ -23,7 +23,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/radio-group/", + "docs": "https://ui.full.dev/astro/components/radio-group/", "categories": [ "ui" ], diff --git a/public/r/rating.json b/public/r/rating.json index 57afb7920..5b7521ad6 100644 --- a/public/r/rating.json +++ b/public/r/rating.json @@ -18,7 +18,7 @@ "type": "registry:ui" } ], - "docs": "https://ui.full.dev/components/rating/", + "docs": "https://ui.full.dev/astro/components/rating/", "categories": [ "ui" ], diff --git a/public/r/react/styles/base-luma/accordion-examples.json b/public/r/react/styles/base-luma/accordion-examples.json new file mode 100644 index 000000000..2cd9c814b --- /dev/null +++ b/public/r/react/styles/base-luma/accordion-examples.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "accordion-examples", + "title": "Accordion examples", + "description": "The examples from the shadcn/ui Accordion docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/card", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/accordion/accordion-basic.tsx", + "content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n\nconst items = [\n {\n value: \"item-1\",\n trigger: \"How do I reset my password?\",\n content:\n \"Click on 'Forgot Password' on the login page, enter your email address, and we'll send you a link to reset your password. The link will expire in 24 hours.\",\n },\n {\n value: \"item-2\",\n trigger: \"Can I change my subscription plan?\",\n content:\n \"Yes, you can upgrade or downgrade your plan at any time from your account settings. Changes will be reflected in your next billing cycle.\",\n },\n {\n value: \"item-3\",\n trigger: \"What payment methods do you accept?\",\n content:\n \"We accept all major credit cards, PayPal, and bank transfers. All payments are processed securely through our payment partners.\",\n },\n]\n\nexport function AccordionBasic() {\n return (\n \n {items.map((item) => (\n \n {item.trigger}\n {item.content}\n \n ))}\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-borders.tsx", + "content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n\nconst items = [\n {\n value: \"billing\",\n trigger: \"How does billing work?\",\n content:\n \"We offer monthly and annual subscription plans. Billing is charged at the beginning of each cycle, and you can cancel anytime. All plans include automatic backups, 24/7 support, and unlimited team members.\",\n },\n {\n value: \"security\",\n trigger: \"Is my data secure?\",\n content:\n \"Yes. We use end-to-end encryption, SOC 2 Type II compliance, and regular third-party security audits. All data is encrypted at rest and in transit using industry-standard protocols.\",\n },\n {\n value: \"integration\",\n trigger: \"What integrations do you support?\",\n content:\n \"We integrate with 500+ popular tools including Slack, Zapier, Salesforce, HubSpot, and more. You can also build custom integrations using our REST API and webhooks.\",\n },\n]\n\nexport function AccordionBorders() {\n return (\n \n {items.map((item) => (\n \n {item.trigger}\n {item.content}\n \n ))}\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-card.tsx", + "content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\n\nconst items = [\n {\n value: \"plans\",\n trigger: \"What subscription plans do you offer?\",\n content:\n \"We offer three subscription tiers: Starter ($9/month), Professional ($29/month), and Enterprise ($99/month). Each plan includes increasing storage limits, API access, priority support, and team collaboration features.\",\n },\n {\n value: \"billing\",\n trigger: \"How does billing work?\",\n content:\n \"Billing occurs automatically at the start of each billing cycle. We accept all major credit cards, PayPal, and ACH transfers for enterprise customers. You'll receive an invoice via email after each payment.\",\n },\n {\n value: \"cancel\",\n trigger: \"How do I cancel my subscription?\",\n content:\n \"You can cancel your subscription anytime from your account settings. There are no cancellation fees or penalties. Your access will continue until the end of your current billing period.\",\n },\n]\n\nexport function AccordionCard() {\n return (\n \n \n Subscription & Billing\n \n Common questions about your account, plans, payments and\n cancellations.\n \n \n \n \n {items.map((item) => (\n \n {item.trigger}\n {item.content}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-demo.tsx", + "content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n\nexport function AccordionDemo() {\n return (\n \n \n What are your shipping options?\n \n We offer standard (5-7 days), express (2-3 days), and overnight\n shipping. Free shipping on international orders.\n \n \n \n What is your return policy?\n \n Returns accepted within 30 days. Items must be unused and in original\n packaging. Refunds processed within 5-7 business days.\n \n \n \n How can I contact customer support?\n \n Reach us via email, live chat, or phone. We respond within 24 hours\n during business days.\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-disabled.tsx", + "content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n\nexport function AccordionDisabled() {\n return (\n \n \n Can I access my account history?\n \n Yes, you can view your complete account history including all\n transactions, plan changes, and support tickets in the Account History\n section of your dashboard.\n \n \n \n Premium feature information\n \n This section contains information about premium features. Upgrade your\n plan to access this content.\n \n \n \n How do I update my email address?\n \n You can update your email address in your account settings.\n You'll receive a verification email at your new address to\n confirm the change.\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-multiple.tsx", + "content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\n\nconst items = [\n {\n value: \"notifications\",\n trigger: \"Notification Settings\",\n content:\n \"Manage how you receive notifications. You can enable email alerts for updates or push notifications for mobile devices.\",\n },\n {\n value: \"privacy\",\n trigger: \"Privacy & Security\",\n content:\n \"Control your privacy settings and security preferences. Enable two-factor authentication, manage connected devices, review active sessions, and configure data sharing preferences. You can also download your data or delete your account.\",\n },\n {\n value: \"billing\",\n trigger: \"Billing & Subscription\",\n content:\n \"View your current plan, payment history, and upcoming invoices. Update your payment method, change your subscription tier, or cancel your subscription.\",\n },\n]\n\nexport function AccordionMultiple() {\n return (\n \n {items.map((item) => (\n \n {item.trigger}\n {item.content}\n \n ))}\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n question1: \"How do I reset my password?\",\n answer1:\n \"Click on 'Forgot Password' on the login page, enter your email address, and we'll send you a link to reset your password.\",\n question2: \"Can I change my subscription plan?\",\n answer2:\n \"Yes, you can upgrade or downgrade your plan at any time from your account settings. Changes will be reflected in your next billing cycle.\",\n question3: \"What payment methods do you accept?\",\n answer3:\n \"We accept all major credit cards, PayPal, and bank transfers. All payments are processed securely through our payment partners.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n question1: \"كيف يمكنني إعادة تعيين كلمة المرور؟\",\n answer1:\n \"انقر على 'نسيت كلمة المرور' في صفحة تسجيل الدخول، أدخل عنوان بريدك الإلكتروني، وسنرسل لك رابطًا لإعادة تعيين كلمة المرور. سينتهي صلاحية الرابط خلال 24 ساعة.\",\n question2: \"هل يمكنني تغيير خطة الاشتراك الخاصة بي؟\",\n answer2:\n \"نعم، يمكنك ترقية أو تخفيض خطتك في أي وقت من إعدادات حسابك. ستظهر التغييرات في دورة الفوترة التالية.\",\n question3: \"ما هي طرق الدفع التي تقبلونها؟\",\n answer3:\n \"نقبل جميع بطاقات الائتمان الرئيسية و PayPal والتحويلات المصرفية. تتم معالجة جميع المدفوعات بأمان من خلال شركاء الدفع لدينا.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n question1: \"איך אני מאפס את הסיסמה שלי?\",\n answer1:\n \"לחץ על 'שכחתי סיסמה' בעמוד ההתחברות, הזן את כתובת האימייל שלך, ונשלח לך קישור לאיפוס הסיסמה. הקישור יפוג תוך 24 שעות.\",\n question2: \"האם אני יכול לשנות את תוכנית המנוי שלי?\",\n answer2:\n \"כן, אתה יכול לשדרג או להוריד את התוכנית שלך בכל עת מההגדרות של החשבון שלך. השינויים יבואו לידי ביטוי במחזור החיוב הבא.\",\n question3: \"אילו אמצעי תשלום אתם מקבלים?\",\n answer3: \"אנו מקבלים כרטיסי אשראי, PayPal והעברות בנקאיות.\",\n },\n },\n}\n\nconst items = [\n {\n value: \"item-1\",\n questionKey: \"question1\" as const,\n answerKey: \"answer1\" as const,\n },\n {\n value: \"item-2\",\n questionKey: \"question2\" as const,\n answerKey: \"answer2\" as const,\n },\n {\n value: \"item-3\",\n questionKey: \"question3\" as const,\n answerKey: \"answer3\" as const,\n },\n] as const\n\nexport function AccordionRtl() {\n const { t } = useTranslation(translations, \"ar\")\n\n return (\n \n {items.map((item) => (\n \n {t[item.questionKey]}\n {t[item.answerKey]}\n \n ))}\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/accordion/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/accordion.json b/public/r/react/styles/base-luma/accordion.json new file mode 100644 index 000000000..9a483c12f --- /dev/null +++ b/public/r/react/styles/base-luma/accordion.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "accordion", + "title": "Accordion", + "description": "A vertically stacked set of interactive headings that each reveal a section of content.", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/accordion.tsx", + "content": "import { Accordion as AccordionPrimitive } from \"@base-ui/react/accordion\"\nimport { cn } from \"cn\"\nimport { ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\n\nfunction Accordion({ className, ...props }: AccordionPrimitive.Root.Props) {\n return (\n \n )\n}\n\nfunction AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props) {\n return (\n \n )\n}\n\nfunction AccordionTrigger({\n className,\n children,\n ...props\n}: AccordionPrimitive.Trigger.Props) {\n return (\n \n \n {children}\n \n \n )\n}\n\nfunction AccordionContent({\n className,\n children,\n ...props\n}: AccordionPrimitive.Panel.Props) {\n return (\n \n \n {children}\n \n \n )\n}\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/accordion/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/alert-dialog-examples.json b/public/r/react/styles/base-luma/alert-dialog-examples.json new file mode 100644 index 000000000..84e2ebeae --- /dev/null +++ b/public/r/react/styles/base-luma/alert-dialog-examples.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "alert-dialog-examples", + "title": "Alert Dialog examples", + "description": "The examples from the shadcn/ui Alert Dialog docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/alert-dialog", + "@fulldev/button", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/alert-dialog/alert-dialog-basic.tsx", + "content": "import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\nimport { Button } from \"@/components/ui/button\"\n\nexport function AlertDialogBasic() {\n return (\n \n Show Dialog}\n />\n \n \n Are you absolutely sure?\n \n This action cannot be undone. This will permanently delete your\n account and remove your data from our servers.\n \n \n \n Cancel\n Continue\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-demo.tsx", + "content": "import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\nimport { Button } from \"@/components/ui/button\"\n\nexport function AlertDialogDemo() {\n return (\n \n }>\n Show Dialog\n \n \n \n Are you absolutely sure?\n \n This action cannot be undone. This will permanently delete your\n account from our servers.\n \n \n \n Cancel\n Continue\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-destructive.tsx", + "content": "import { Trash2Icon } from \"lucide-react\"\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\nimport { Button } from \"@/components/ui/button\"\n\nexport function AlertDialogDestructive() {\n return (\n \n Delete Chat}\n />\n \n \n \n \n \n Delete chat?\n \n This will permanently delete this chat conversation. View{\" \"}\n Settings delete any memories saved during this chat.\n \n \n \n Cancel\n Delete\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-media.tsx", + "content": "import { CircleFadingPlusIcon } from \"lucide-react\"\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\nimport { Button } from \"@/components/ui/button\"\n\nexport function AlertDialogWithMedia() {\n return (\n \n Share Project}\n />\n \n \n \n \n \n Share this project?\n \n Anyone with the link will be able to view and edit this project.\n \n \n \n Cancel\n Share\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-rtl.tsx", + "content": "\"use client\"\n\nimport { BluetoothIcon } from \"lucide-react\"\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n showDialog: \"Show Dialog\",\n showDialogSm: \"Show Dialog (sm)\",\n title: \"Are you absolutely sure?\",\n description:\n \"This action cannot be undone. This will permanently delete your account from our servers.\",\n cancel: \"Cancel\",\n continue: \"Continue\",\n smallTitle: \"Allow accessory to connect?\",\n smallDescription:\n \"Do you want to allow the USB accessory to connect to this device?\",\n dontAllow: \"Don't allow\",\n allow: \"Allow\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n showDialog: \"إظهار الحوار\",\n showDialogSm: \"إظهار الحوار (صغير)\",\n title: \"هل أنت متأكد تمامًا؟\",\n description:\n \"لا يمكن التراجع عن هذا الإجراء. سيؤدي هذا إلى حذف حسابك نهائيًا من خوادمنا.\",\n cancel: \"إلغاء\",\n continue: \"متابعة\",\n smallTitle: \"السماح للملحق بالاتصال؟\",\n smallDescription: \"هل تريد السماح لملحق USB بالاتصال بهذا الجهاز؟\",\n dontAllow: \"عدم السماح\",\n allow: \"السماح\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n showDialog: \"הצג דיאלוג\",\n showDialogSm: \"הצג דיאלוג (קטן)\",\n title: \"האם אתה בטוח לחלוטין?\",\n description:\n \"פעולה זו לא ניתנת לביטול. זה ימחק לצמיתות את החשבון שלך מהשרתים שלנו.\",\n cancel: \"ביטול\",\n continue: \"המשך\",\n smallTitle: \"לאפשר להתקן להתחבר?\",\n smallDescription: \"האם אתה רוצה לאפשר להתקן USB להתחבר למכשיר זה?\",\n dontAllow: \"אל תאפשר\",\n allow: \"אפשר\",\n },\n },\n}\n\nexport function AlertDialogRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n\n return (\n
\n \n }>\n {t.showDialog}\n \n \n \n {t.title}\n {t.description}\n \n \n {t.cancel}\n {t.continue}\n \n \n \n \n }>\n {t.showDialogSm}\n \n \n \n \n \n \n {t.smallTitle}\n \n {t.smallDescription}\n \n \n \n {t.dontAllow}\n {t.allow}\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-small-media.tsx", + "content": "import { BluetoothIcon } from \"lucide-react\"\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\nimport { Button } from \"@/components/ui/button\"\n\nexport function AlertDialogSmallWithMedia() {\n return (\n \n Show Dialog}\n />\n\n \n \n \n \n \n Allow accessory to connect?\n \n Do you want to allow the USB accessory to connect to this device?\n \n \n \n Don't allow\n Allow\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-small.tsx", + "content": "import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\nimport { Button } from \"@/components/ui/button\"\n\nexport function AlertDialogSmall() {\n return (\n \n Show Dialog}\n />\n \n \n Allow accessory to connect?\n \n Do you want to allow the USB accessory to connect to this device?\n \n \n \n Don't allow\n Allow\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/alert-dialog/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/alert-dialog.json b/public/r/react/styles/base-luma/alert-dialog.json new file mode 100644 index 000000000..800741d93 --- /dev/null +++ b/public/r/react/styles/base-luma/alert-dialog.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "alert-dialog", + "title": "Alert Dialog", + "description": "A modal dialog for important confirmations that expects a response.", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/alert-dialog.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { AlertDialog as AlertDialogPrimitive } from \"@base-ui/react/alert-dialog\"\nimport { cn } from \"cn\"\n\nimport { Button } from \"@/components/ui/button\"\n\nfunction AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {\n return \n}\n\nfunction AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {\n return (\n \n )\n}\n\nfunction AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {\n return (\n \n )\n}\n\nfunction AlertDialogOverlay({\n className,\n ...props\n}: AlertDialogPrimitive.Backdrop.Props) {\n return (\n \n )\n}\n\nfunction AlertDialogContent({\n className,\n size = \"default\",\n ...props\n}: AlertDialogPrimitive.Popup.Props & {\n size?: \"default\" | \"sm\"\n}) {\n return (\n \n \n \n \n )\n}\n\nfunction AlertDialogHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction AlertDialogFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction AlertDialogMedia({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction AlertDialogTitle({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction AlertDialogDescription({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction AlertDialogAction({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction AlertDialogCancel({\n className,\n variant = \"outline\",\n size = \"default\",\n ...props\n}: AlertDialogPrimitive.Close.Props &\n Pick, \"variant\" | \"size\">) {\n return (\n }\n {...props}\n />\n )\n}\n\nexport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogOverlay,\n AlertDialogPortal,\n AlertDialogTitle,\n AlertDialogTrigger,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/alert-dialog/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/alert-examples.json b/public/r/react/styles/base-luma/alert-examples.json new file mode 100644 index 000000000..dc5eeedfc --- /dev/null +++ b/public/r/react/styles/base-luma/alert-examples.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "alert-examples", + "title": "Alert examples", + "description": "The examples from the shadcn/ui Alert docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/alert", + "@fulldev/button", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/alert/alert-action.tsx", + "content": "import {\n Alert,\n AlertAction,\n AlertDescription,\n AlertTitle,\n} from \"@/components/ui/alert\"\nimport { Button } from \"@/components/ui/button\"\n\nexport function AlertActionExample() {\n return (\n \n Dark mode is now available\n \n Enable it under your profile settings to get started.\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-basic.tsx", + "content": "import { CheckCircle2Icon } from \"lucide-react\"\n\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\"\n\nexport function AlertBasic() {\n return (\n \n \n Account updated successfully\n \n Your profile information has been saved. Changes will be reflected\n immediately.\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-colors.tsx", + "content": "import { AlertTriangleIcon } from \"lucide-react\"\n\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\"\n\nexport function AlertColors() {\n return (\n \n \n Your subscription will expire in 3 days.\n \n Renew now to avoid service interruption or upgrade to a paid plan to\n continue using the service.\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-demo.tsx", + "content": "import { CheckCircle2Icon, InfoIcon } from \"lucide-react\"\n\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\"\n\nexport function AlertDemo() {\n return (\n
\n \n \n Payment successful\n \n Your payment of $29.99 has been processed. A receipt has been sent to\n your email address.\n \n \n \n \n New feature available\n \n We've added dark mode support. You can enable it in your account\n settings.\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-destructive.tsx", + "content": "import { AlertCircleIcon } from \"lucide-react\"\n\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\"\n\nexport function AlertDestructive() {\n return (\n \n \n Payment failed\n \n Your payment could not be processed. Please check your payment method\n and try again.\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { CheckCircle2Icon, InfoIcon } from \"lucide-react\"\n\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n paymentTitle: \"Payment successful\",\n paymentDescription:\n \"Your payment of $29.99 has been processed. A receipt has been sent to your email address.\",\n featureTitle: \"New feature available\",\n featureDescription:\n \"We've added dark mode support. You can enable it in your account settings.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n paymentTitle: \"تم الدفع بنجاح\",\n paymentDescription:\n \"تمت معالجة دفعتك البالغة 29.99 دولارًا. تم إرسال إيصال إلى عنوان بريدك الإلكتروني.\",\n featureTitle: \"ميزة جديدة متاحة\",\n featureDescription:\n \"لقد أضفنا دعم الوضع الداكن. يمكنك تفعيله في إعدادات حسابك.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n paymentTitle: \"התשלום בוצע בהצלחה\",\n paymentDescription:\n \"התשלום שלך בסך 29.99 דולר עובד. קבלה נשלחה לכתובת האימייל שלך.\",\n featureTitle: \"תכונה חדשה זמינה\",\n featureDescription:\n \"הוספנו תמיכה במצב כהה. אתה יכול להפעיל אותו בהגדרות החשבון שלך.\",\n },\n },\n}\n\nconst alerts = [\n {\n icon: CheckCircle2Icon,\n titleKey: \"paymentTitle\" as const,\n descriptionKey: \"paymentDescription\" as const,\n },\n {\n icon: InfoIcon,\n titleKey: \"featureTitle\" as const,\n descriptionKey: \"featureDescription\" as const,\n },\n] as const\n\nexport function AlertRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n
\n {alerts.map((alert, index) => {\n const Icon = alert.icon\n return (\n \n \n {t[alert.titleKey]}\n {t[alert.descriptionKey]}\n \n )\n })}\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/alert/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/alert.json b/public/r/react/styles/base-luma/alert.json new file mode 100644 index 000000000..bc7a2fb54 --- /dev/null +++ b/public/r/react/styles/base-luma/alert.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "alert", + "title": "Alert", + "description": "Displays a callout for user attention.", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/alert.tsx", + "content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nconst alertVariants = cva(\"grid gap-0.5 rounded-2xl border px-4 py-3 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 group/alert relative w-full\", {\n variants: {\n variant: {\n default: \"bg-card text-card-foreground\",\n destructive: \"text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n})\n\nfunction Alert({\n className,\n variant,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps) {\n return (\n \n )\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction AlertAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nexport { Alert, AlertTitle, AlertDescription, AlertAction }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/alert/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/article-1.json b/public/r/react/styles/base-luma/article-1.json new file mode 100644 index 000000000..72c6789be --- /dev/null +++ b/public/r/react/styles/base-luma/article-1.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "article-1", + "title": "Article 1", + "description": "Editorial article layouts for long-form stories, interviews, and analysis.", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/article-1.tsx", + "content": "import * as React from \"react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Article1({\n title,\n description,\n author,\n image,\n children,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n author: {\n image?: string\n initials: string\n name: string\n date: string\n }\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n}) {\n return (\n
\n \n
\n
\n
\n

\n {title}\n

\n

\n {description}\n

\n
\n
\n \n \n {author.initials}\n \n
\n

{author.name}

\n

{author.date}

\n
\n
\n
\n \n
\n {children}\n
\n
\n
\n
\n )\n}\n\nexport { Article1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/article/", + "categories": [ + "article" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/article-2.json b/public/r/react/styles/base-luma/article-2.json new file mode 100644 index 000000000..35afdfbf4 --- /dev/null +++ b/public/r/react/styles/base-luma/article-2.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "article-2", + "title": "Article 2", + "description": "Editorial article layouts for long-form stories, interviews, and analysis.", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/article-2.tsx", + "content": "import * as React from \"react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Article2({\n title,\n description,\n author,\n image,\n children,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n author: {\n image?: string\n initials: string\n name: string\n date: string\n readingTime: string\n }\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n}) {\n return (\n
\n \n
\n
\n
\n

\n {title}\n

\n

\n {description}\n

\n
\n
\n \n \n {author.initials}\n \n
\n

\n {author.name}{\" \"}\n \n · {author.date}\n \n

\n

\n {author.readingTime}\n

\n
\n
\n
\n \n
\n {children}\n
\n
\n
\n
\n )\n}\n\nexport { Article2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/article/", + "categories": [ + "article" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/articles-1.json b/public/r/react/styles/base-luma/articles-1.json new file mode 100644 index 000000000..6d08b90ac --- /dev/null +++ b/public/r/react/styles/base-luma/articles-1.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "articles-1", + "title": "Articles 1", + "description": "Collection and listing layouts for journals, magazines, and editorial feeds.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/articles-1.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Articles1({\n title,\n description,\n articles,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n articles: {\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: string\n initials: string\n name: string\n date: string\n }\n }[]\n}) {\n return (\n
\n \n
\n {title}\n

\n {description}\n

\n
\n\n
\n {articles.map((article) => {\n const className = cn(\n \"flex h-full flex-col gap-4 rounded-xl p-4\",\n article.href != null &&\n \"group transition-colors hover:bg-muted/50 focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:outline-none\"\n )\n const content = (\n <>\n \n
\n

\n {article.category}\n

\n

\n {article.title}\n

\n

\n {article.description}\n

\n
\n
\n \n \n {article.author.initials}\n \n
\n

{article.author.name}

\n

\n {article.author.date}\n

\n
\n
\n \n )\n return article.href != null ? (\n \n {content}\n \n ) : (\n
\n {content}\n
\n )\n })}\n
\n
\n
\n )\n}\n\nexport { Articles1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/articles/", + "categories": [ + "articles" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/articles-2.json b/public/r/react/styles/base-luma/articles-2.json new file mode 100644 index 000000000..8dc136d84 --- /dev/null +++ b/public/r/react/styles/base-luma/articles-2.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "articles-2", + "title": "Articles 2", + "description": "Collection and listing layouts for journals, magazines, and editorial feeds.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/badge", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/articles-2.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Articles2({\n title,\n description,\n featured,\n articles,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n featured: {\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: string\n initials: string\n name: string\n date: string\n }\n }\n articles: {\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: string\n initials: string\n name: string\n date: string\n }\n }[]\n}) {\n const featuredClassName = cn(\n \"grid gap-6 rounded-xl lg:grid-cols-2 lg:items-center lg:pr-4\",\n featured.href != null &&\n \"group transition-colors hover:bg-muted/50 focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:outline-none\"\n )\n const featuredContent = (\n <>\n \n
\n \n {featured.category}\n \n

\n {featured.title}\n

\n

\n {featured.description}\n

\n
\n \n \n {featured.author.initials}\n \n
\n

{featured.author.name}

\n

\n {featured.author.date}\n

\n
\n
\n
\n \n )\n\n return (\n
\n \n
\n

\n {title}\n

\n

\n {description}\n

\n
\n\n {featured.href != null ? (\n \n {featuredContent}\n \n ) : (\n
{featuredContent}
\n )}\n\n
\n {articles.map((article) => {\n const className = cn(\n \"flex h-full flex-col gap-4 rounded-xl p-4\",\n article.href != null &&\n \"group transition-colors hover:bg-muted/50 focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:outline-none\"\n )\n const content = (\n <>\n \n
\n

\n {article.category}\n

\n

\n {article.title}\n

\n

\n {article.description}\n

\n
\n
\n \n \n {article.author.initials}\n \n
\n

{article.author.name}

\n

\n {article.author.date}\n

\n
\n
\n \n )\n return article.href != null ? (\n \n {content}\n \n ) : (\n
\n {content}\n
\n )\n })}\n
\n
\n
\n )\n}\n\nexport { Articles2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/articles/", + "categories": [ + "articles" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/articles-3.json b/public/r/react/styles/base-luma/articles-3.json new file mode 100644 index 000000000..61b4dde41 --- /dev/null +++ b/public/r/react/styles/base-luma/articles-3.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "articles-3", + "title": "Articles 3", + "description": "Collection and listing layouts for journals, magazines, and editorial feeds.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/articles-3.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Articles3({\n title,\n articles,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n articles: {\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: string\n initials: string\n name: string\n date: string\n }\n }[]\n}) {\n return (\n
\n \n
\n
\n {title}\n
\n
\n\n
\n {articles.map((article) => {\n const className = cn(\n \"flex h-full flex-col gap-4 rounded-xl bg-muted/50 p-4\",\n article.href != null &&\n \"group transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:outline-none\"\n )\n const content = (\n <>\n \n
\n

\n {article.category}\n

\n

\n {article.title}\n

\n

\n {article.description}\n

\n
\n
\n \n \n {article.author.initials}\n \n
\n

{article.author.name}

\n

\n {article.author.date}\n

\n
\n
\n \n )\n return article.href != null ? (\n \n {content}\n \n ) : (\n
\n {content}\n
\n )\n })}\n
\n
\n
\n )\n}\n\nexport { Articles3 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/articles/", + "categories": [ + "articles" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/articles-4.json b/public/r/react/styles/base-luma/articles-4.json new file mode 100644 index 000000000..eb8bd0c5a --- /dev/null +++ b/public/r/react/styles/base-luma/articles-4.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "articles-4", + "title": "Articles 4", + "description": "Collection and listing layouts for journals, magazines, and editorial feeds.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/articles-4.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Articles4({\n title,\n description,\n articles,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n articles: {\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: string\n initials: string\n name: string\n date: string\n }\n }[]\n}) {\n return (\n
\n \n
\n

\n {title}\n

\n

\n {description}\n

\n
\n\n
\n {articles.map((article) => {\n const className = cn(\n \"flex h-full flex-col gap-4 rounded-xl border p-6\",\n article.href != null &&\n \"group transition-colors hover:bg-muted/50 focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:outline-none\"\n )\n const content = (\n <>\n
\n

\n {article.category}\n

\n

\n {article.title}\n

\n

\n {article.description}\n

\n
\n
\n \n \n {article.author.initials}\n \n
\n

{article.author.name}

\n

\n {article.author.date}\n

\n
\n
\n \n )\n return article.href != null ? (\n \n {content}\n \n ) : (\n
\n {content}\n
\n )\n })}\n
\n
\n
\n )\n}\n\nexport { Articles4 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/articles/", + "categories": [ + "articles" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/aspect-ratio-examples.json b/public/r/react/styles/base-luma/aspect-ratio-examples.json new file mode 100644 index 000000000..af8ad813d --- /dev/null +++ b/public/r/react/styles/base-luma/aspect-ratio-examples.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "aspect-ratio-examples", + "title": "Aspect Ratio examples", + "description": "The examples from the shadcn/ui Aspect Ratio docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/aspect-ratio", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-demo.tsx", + "content": "import { AspectRatio } from \"@/components/ui/aspect-ratio\"\n\nexport function AspectRatioDemo() {\n return (\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-portrait.tsx", + "content": "import { AspectRatio } from \"@/components/ui/aspect-ratio\"\n\nexport function AspectRatioPortrait() {\n return (\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { AspectRatio } from \"@/components/ui/aspect-ratio\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n caption: \"Beautiful landscape\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n caption: \"منظر طبيعي جميل\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n caption: \"נוף יפה\",\n },\n },\n}\n\nexport function AspectRatioRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n
\n \n \n \n
\n {t.caption}\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-square.tsx", + "content": "import { AspectRatio } from \"@/components/ui/aspect-ratio\"\n\nexport function AspectRatioSquare() {\n return (\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/aspect-ratio/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/aspect-ratio.json b/public/r/react/styles/base-luma/aspect-ratio.json new file mode 100644 index 000000000..011cf513d --- /dev/null +++ b/public/r/react/styles/base-luma/aspect-ratio.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "aspect-ratio", + "title": "Aspect Ratio", + "description": "Displays content within a desired ratio.", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/aspect-ratio.tsx", + "content": "import { cn } from \"cn\"\n\nfunction AspectRatio({\n ratio,\n className,\n ...props\n}: React.ComponentProps<\"div\"> & { ratio: number }) {\n return (\n \n )\n}\n\nexport { AspectRatio }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/aspect-ratio/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/attachment-examples.json b/public/r/react/styles/base-luma/attachment-examples.json new file mode 100644 index 000000000..0f38e2ed6 --- /dev/null +++ b/public/r/react/styles/base-luma/attachment-examples.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "attachment-examples", + "title": "Attachment examples", + "description": "The examples from the shadcn/ui Attachment docs.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/attachment", + "@fulldev/dialog", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/attachment/attachment-demo.tsx", + "content": "import { FileCodeIcon, XIcon } from \"lucide-react\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentGroup,\n AttachmentMedia,\n AttachmentTitle,\n} from \"@/components/ui/attachment\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\nconst images = [\n {\n name: \"workspace.png\",\n meta: \"PNG · 820 KB\",\n src: \"https://images.unsplash.com/photo-1497366754035-f200968a6e72?w=900&auto=format&fit=crop&q=80\",\n alt: \"Workspace\",\n },\n {\n name: \"desk-reference.jpg\",\n meta: \"JPG · 1.1 MB\",\n src: \"https://images.unsplash.com/photo-1497215728101-856f4ea42174?w=900&auto=format&fit=crop&q=80\",\n alt: \"Desk\",\n },\n {\n name: \"office-reference.jpg\",\n meta: \"JPG · 940 KB\",\n src: \"https://images.unsplash.com/photo-1497366811353-6870744d04b2?w=900&auto=format&fit=crop&q=80\",\n alt: \"Office\",\n },\n]\n\nexport function AttachmentDemo() {\n return (\n
\n \n {images.map((image) => (\n \n \n {image.alt}\n \n \n {image.name}\n {image.meta}\n \n \n ))}\n \n \n \n \n \n \n sales-dashboard.pdf\n Uploading · 64%\n \n \n \n \n \n \n \n \n \n \n \n \n message-renderer.tsx\n TypeScript · 12 KB\n \n \n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-group.tsx", + "content": "import {\n FileCodeIcon,\n FileTextIcon,\n TableIcon,\n XIcon,\n type LucideIcon,\n} from \"lucide-react\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentGroup,\n AttachmentMedia,\n AttachmentTitle,\n} from \"@/components/ui/attachment\"\n\ntype Item = {\n name: string\n meta: string\n icon?: LucideIcon\n src?: string\n}\n\nconst items: Item[] = [\n { name: \"briefing-notes.pdf\", meta: \"PDF · 1.4 MB\", icon: FileTextIcon },\n {\n name: \"workspace.png\",\n meta: \"PNG · 820 KB\",\n src: \"https://images.unsplash.com/photo-1497366754035-f200968a6e72?w=900&auto=format&fit=crop&q=80\",\n },\n { name: \"customers.csv\", meta: \"CSV · 18 KB\", icon: TableIcon },\n { name: \"renderer.tsx\", meta: \"TSX · 12 KB\", icon: FileCodeIcon },\n]\n\nexport function AttachmentGroupDemo() {\n return (\n
\n \n {items.map((item) => {\n const Icon = item.icon\n\n return (\n \n {item.src ? (\n \n {item.name}\n \n ) : Icon ? (\n \n \n \n ) : null}\n \n {item.name}\n {item.meta}\n \n \n \n \n \n \n \n )\n })}\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-image.tsx", + "content": "import { XIcon } from \"lucide-react\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentGroup,\n AttachmentMedia,\n AttachmentTitle,\n AttachmentTrigger,\n} from \"@/components/ui/attachment\"\n\nconst images = [\n {\n name: \"workspace.png\",\n meta: \"PNG · 820 KB\",\n src: \"https://images.unsplash.com/photo-1497366754035-f200968a6e72?w=900&auto=format&fit=crop&q=80\",\n alt: \"Workspace\",\n },\n {\n name: \"desk-reference.jpg\",\n meta: \"JPG · 1.1 MB\",\n src: \"https://images.unsplash.com/photo-1497215728101-856f4ea42174?w=900&auto=format&fit=crop&q=80\",\n alt: \"Desk\",\n },\n {\n name: \"office-reference.jpg\",\n meta: \"JPG · 940 KB\",\n src: \"https://images.unsplash.com/photo-1497366811353-6870744d04b2?w=900&auto=format&fit=crop&q=80\",\n alt: \"Office\",\n },\n]\n\nexport function AttachmentImage() {\n return (\n
\n \n {images.map((image) => (\n \n \n {image.alt}\n \n \n {image.name}\n {image.meta}\n \n \n \n \n \n \n \n }\n />\n \n ))}\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-sizes.tsx", + "content": "import { FileTextIcon } from \"lucide-react\"\n\nimport {\n Attachment,\n AttachmentContent,\n AttachmentDescription,\n AttachmentMedia,\n AttachmentTitle,\n} from \"@/components/ui/attachment\"\n\nexport function AttachmentSizes() {\n return (\n
\n \n \n \n \n \n Default attachment\n PDF · 2.4 MB\n \n \n \n \n \n \n \n Small attachment\n PDF · 2.4 MB\n \n \n \n \n \n \n \n Extra small attachment\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-states.tsx", + "content": "import {\n CheckIcon,\n ClockIcon,\n FileTextIcon,\n FileWarningIcon,\n RefreshCwIcon,\n XIcon,\n} from \"lucide-react\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentMedia,\n AttachmentTitle,\n} from \"@/components/ui/attachment\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\nexport function AttachmentStates() {\n return (\n
\n \n \n \n \n \n selected-file.pdf\n Ready to upload\n \n \n \n \n \n \n \n \n \n \n \n \n design-system.zip\n Uploading · 64%\n \n \n \n \n \n \n \n \n \n \n \n \n market-research.pdf\n Processing document\n \n \n \n \n \n \n \n \n \n \n \n \n financial-model.xlsx\n \n Upload failed. Try again.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n uploaded-report.pdf\n Uploaded · 1.8 MB\n \n \n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-trigger.tsx", + "content": "import { CopyIcon, FileSearchIcon, XIcon } from \"lucide-react\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentMedia,\n AttachmentTitle,\n AttachmentTrigger,\n} from \"@/components/ui/attachment\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\"\n\nexport function AttachmentTriggerDemo() {\n return (\n
\n \n \n \n \n \n \n research-summary.pdf\n Open preview dialog\n \n \n \n \n \n \n \n \n \n \n }\n />\n \n \n \n research-summary.pdf\n \n The attachment trigger fills the card and opens the dialog, while\n the actions stay independently clickable above it.\n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/attachment/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/attachment.json b/public/r/react/styles/base-luma/attachment.json new file mode 100644 index 000000000..0b253c7f6 --- /dev/null +++ b/public/r/react/styles/base-luma/attachment.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "attachment", + "title": "Attachment", + "description": "Displays a file or image attachment with media, metadata, state, and actions.", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/attachment.tsx", + "content": "import * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nimport { Button } from \"@/components/ui/button\"\n\nconst attachmentVariants = cva(\n \"rounded-3xl w-fit focus-within:ring-1 focus-within:ring-ring/30 group/attachment relative flex max-w-full min-w-0 shrink-0 flex-wrap border bg-card text-card-foreground transition-colors has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed\",\n {\n variants: {\n size: {\n default: \"gap-2 has-data-[slot=attachment-content]:px-2.5 has-data-[slot=attachment-content]:py-2 has-data-[slot=attachment-media]:p-2 text-sm\",\n sm: \"gap-2.5 has-data-[slot=attachment-content]:px-2 has-data-[slot=attachment-content]:py-1.5 has-data-[slot=attachment-media]:p-1.5 text-xs\",\n xs: \"gap-1.5 has-data-[slot=attachment-content]:px-1.5 has-data-[slot=attachment-content]:py-1 has-data-[slot=attachment-media]:p-1 text-xs rounded-2xl\",\n },\n orientation: {\n horizontal: \"min-w-40 items-center\",\n vertical: \"w-24 has-data-[slot=attachment-content]:w-30 flex-col\",\n },\n },\n }\n)\n\nfunction Attachment({\n className,\n state = \"done\",\n size = \"default\",\n orientation = \"horizontal\",\n ...props\n}: React.ComponentProps<\"div\"> &\n VariantProps & {\n state?: \"idle\" | \"uploading\" | \"processing\" | \"error\" | \"done\"\n }) {\n return (\n \n )\n}\n\nconst attachmentMediaVariants = cva(\n \"bg-muted text-foreground w-10 rounded-2xl group-data-[size=sm]/attachment:w-8 group-data-[size=xs]/attachment:w-7 group-data-[size=xs]/attachment:rounded-xl [&_svg:not([class*='size-'])]:size-4 group-data-[size=xs]/attachment:[&_svg:not([class*='size-'])]:size-3.5 group-data-[orientation=vertical]/attachment:w-full group-data-[orientation=vertical]/attachment:[&_svg:not([class*='size-'])]:size-6 group-data-[orientation=vertical]/attachment:*:data-[slot=spinner]:size-6! relative flex aspect-square shrink-0 items-center justify-center overflow-hidden group-data-[state=error]/attachment:bg-destructive/10 group-data-[state=error]/attachment:text-destructive [&_svg]:pointer-events-none\",\n {\n variants: {\n variant: {\n icon: \"\",\n image:\n \"opacity-60 group-data-[state=idle]/attachment:opacity-100 group-data-[state=done]/attachment:opacity-100 *:[img]:aspect-square *:[img]:w-full *:[img]:object-cover\",\n },\n },\n defaultVariants: {\n variant: \"icon\",\n },\n }\n)\n\nfunction AttachmentMedia({\n className,\n variant = \"icon\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps) {\n return (\n \n )\n}\n\nfunction AttachmentContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction AttachmentTitle({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n \n )\n}\n\nfunction AttachmentDescription({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n \n )\n}\n\nfunction AttachmentActions({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction AttachmentAction({\n className,\n variant,\n size = \"icon-xs\",\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction AttachmentTrigger({\n className,\n render,\n type,\n ...props\n}: useRender.ComponentProps<\"button\">) {\n return useRender({\n defaultTagName: \"button\",\n props: mergeProps<\"button\">(\n {\n type: render ? type : (type ?? \"button\"),\n className: cn(\n \"absolute inset-0 z-10 outline-none\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"attachment-trigger\",\n },\n })\n}\n\nfunction AttachmentGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nexport {\n Attachment,\n AttachmentGroup,\n AttachmentMedia,\n AttachmentContent,\n AttachmentTitle,\n AttachmentDescription,\n AttachmentActions,\n AttachmentAction,\n AttachmentTrigger,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/attachment/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/avatar-examples.json b/public/r/react/styles/base-luma/avatar-examples.json new file mode 100644 index 000000000..dc7a94ec9 --- /dev/null +++ b/public/r/react/styles/base-luma/avatar-examples.json @@ -0,0 +1,75 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "avatar-examples", + "title": "Avatar examples", + "description": "The examples from the shadcn/ui Avatar docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/avatar/avatar-badge-icon.tsx", + "content": "import { PlusIcon } from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarBadge,\n AvatarFallback,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n\nexport function AvatarBadgeIconExample() {\n return (\n \n \n PP\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-badge.tsx", + "content": "import {\n Avatar,\n AvatarBadge,\n AvatarFallback,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n\nexport function AvatarWithBadge() {\n return (\n \n \n CN\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-basic.tsx", + "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\n\nexport function AvatarDemo() {\n return (\n \n \n CN\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-demo.tsx", + "content": "import {\n Avatar,\n AvatarBadge,\n AvatarFallback,\n AvatarGroup,\n AvatarGroupCount,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n\nexport function AvatarDemo() {\n return (\n
\n \n \n CN\n \n \n \n ER\n \n \n \n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n +3\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-dropdown.tsx", + "content": "\"use client\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function AvatarDropdown() {\n return (\n \n }\n >\n \n \n CN\n \n \n \n \n Profile\n Billing\n Settings\n \n \n \n Log out\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-group-count-icon.tsx", + "content": "import { PlusIcon } from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarGroupCount,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n\nexport function AvatarGroupCountIconExample() {\n return (\n \n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-group-count.tsx", + "content": "import {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarGroupCount,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n\nexport function AvatarGroupCountExample() {\n return (\n \n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n +3\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-group.tsx", + "content": "import {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarImage,\n} from \"@/components/ui/avatar\"\n\nexport function AvatarGroupExample() {\n return (\n \n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Avatar,\n AvatarBadge,\n AvatarFallback,\n AvatarGroup,\n AvatarGroupCount,\n AvatarImage,\n} from \"@/components/ui/avatar\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n moreUsers: \"+3\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n moreUsers: \"+٣\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n moreUsers: \"+3\",\n },\n },\n}\n\nexport function AvatarRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n \n \n \n CN\n \n \n \n ER\n \n \n \n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n {t.moreUsers}\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-size.tsx", + "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\n\nexport function AvatarSizeExample() {\n return (\n
\n \n \n CN\n \n \n \n CN\n \n \n \n CN\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/avatar/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/avatar.json b/public/r/react/styles/base-luma/avatar.json new file mode 100644 index 000000000..e7c29b38c --- /dev/null +++ b/public/r/react/styles/base-luma/avatar.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "avatar", + "title": "Avatar", + "description": "An image element with a fallback for representing the user.", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/avatar.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Avatar as AvatarPrimitive } from \"@base-ui/react/avatar\"\nimport { cn } from \"cn\"\n\nfunction Avatar({\n className,\n size = \"default\",\n ...props\n}: AvatarPrimitive.Root.Props & {\n size?: \"default\" | \"sm\" | \"lg\"\n}) {\n return (\n \n )\n}\n\nfunction AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) {\n return (\n \n )\n}\n\nfunction AvatarFallback({\n className,\n ...props\n}: AvatarPrimitive.Fallback.Props) {\n return (\n \n )\n}\n\nfunction AvatarBadge({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n svg]:hidden\",\n \"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2\",\n \"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AvatarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction AvatarGroupCount({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3 relative flex shrink-0 items-center justify-center ring-2 ring-background\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Avatar,\n AvatarImage,\n AvatarFallback,\n AvatarGroup,\n AvatarGroupCount,\n AvatarBadge,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/avatar/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/badge-examples.json b/public/r/react/styles/base-luma/badge-examples.json new file mode 100644 index 000000000..d9f53ea22 --- /dev/null +++ b/public/r/react/styles/base-luma/badge-examples.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "badge-examples", + "title": "Badge examples", + "description": "The examples from the shadcn/ui Badge docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/select", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/badge/badge-colors.tsx", + "content": "import { Badge } from \"@/components/ui/badge\"\n\nexport function BadgeCustomColors() {\n return (\n
\n \n Blue\n \n \n Green\n \n \n Sky\n \n \n Purple\n \n \n Red\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-demo.tsx", + "content": "import { Badge } from \"@/components/ui/badge\"\n\nexport function BadgeDemo() {\n return (\n
\n Badge\n Secondary\n Destructive\n Outline\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-icon.tsx", + "content": "import { BadgeCheck, BookmarkIcon } from \"lucide-react\"\n\nimport { Badge } from \"@/components/ui/badge\"\n\nexport function BadgeWithIconLeft() {\n return (\n
\n \n \n Verified\n \n \n Bookmark\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-link.tsx", + "content": "import { ArrowUpRightIcon } from \"lucide-react\"\n\nimport { Badge } from \"@/components/ui/badge\"\n\nexport function BadgeAsLink() {\n return (\n }>\n Open Link \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { BadgeCheck, BookmarkIcon } from \"lucide-react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n badge: \"Badge\",\n secondary: \"Secondary\",\n destructive: \"Destructive\",\n outline: \"Outline\",\n verified: \"Verified\",\n bookmark: \"Bookmark\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n badge: \"شارة\",\n secondary: \"ثانوي\",\n destructive: \"مدمر\",\n outline: \"مخطط\",\n verified: \"متحقق\",\n bookmark: \"إشارة مرجعية\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n badge: \"תג\",\n secondary: \"משני\",\n destructive: \"הרסני\",\n outline: \"קווי מתאר\",\n verified: \"מאומת\",\n bookmark: \"סימנייה\",\n },\n },\n}\n\nexport function BadgeRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n
\n {t.badge}\n {t.secondary}\n {t.destructive}\n {t.outline}\n \n \n {t.verified}\n \n \n {t.bookmark}\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-spinner.tsx", + "content": "import { Badge } from \"@/components/ui/badge\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\nexport function BadgeWithSpinner() {\n return (\n
\n \n \n Deleting\n \n \n Generating\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-variants.tsx", + "content": "import { Badge } from \"@/components/ui/badge\"\n\nexport function BadgeVariants() {\n return (\n
\n Default\n Secondary\n Destructive\n Outline\n Ghost\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/badge/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/badge.json b/public/r/react/styles/base-luma/badge.json new file mode 100644 index 000000000..6420163ee --- /dev/null +++ b/public/r/react/styles/base-luma/badge.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "badge", + "title": "Badge", + "description": "Displays a badge or a component that looks like a badge.", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/badge.tsx", + "content": "import { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nconst badgeVariants = cva(\n \"h-5 gap-1 rounded-3xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! group/badge inline-flex w-fit shrink-0 items-center justify-center overflow-hidden whitespace-nowrap focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground [a]:hover:bg-primary/80\",\n secondary: \"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80\",\n destructive: \"bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20\",\n outline: \"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground\",\n ghost: \"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Badge({\n className,\n variant = \"default\",\n render,\n ...props\n}: useRender.ComponentProps<\"span\"> & VariantProps) {\n return useRender({\n defaultTagName: \"span\",\n props: mergeProps<\"span\">(\n {\n className: cn(badgeVariants({ variant }), className),\n },\n props\n ),\n render,\n state: {\n slot: \"badge\",\n variant,\n },\n })\n}\n\nexport { Badge, badgeVariants }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/badge/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/banner-1.json b/public/r/react/styles/base-luma/banner-1.json new file mode 100644 index 000000000..17e2ea3f3 --- /dev/null +++ b/public/r/react/styles/base-luma/banner-1.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "banner-1", + "title": "Banner 1", + "description": "Announcement and promo bars that sit above or inside page content.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/banner" + ], + "files": [ + { + "path": "src/components/blocks/banner-1.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { Banner, BannerContainer } from \"@/components/ui/banner\"\n\nfunction Banner1({\n className,\n title,\n description,\n link,\n closeLabel,\n storageKey,\n ...props\n}: React.ComponentProps<\"aside\"> & {\n title: string\n description: string\n link: {\n label: string\n href: string\n }\n closeLabel: string\n storageKey?: string\n}) {\n return (\n \n \n

\n {title}{\" \"}\n {\" \"}\n {description}\n

\n \n {link.label}\n \n \n \n \n )\n}\n\nexport { Banner1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/banner/", + "categories": [ + "banner" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/banner-2.json b/public/r/react/styles/base-luma/banner-2.json new file mode 100644 index 000000000..ccc3eda90 --- /dev/null +++ b/public/r/react/styles/base-luma/banner-2.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "banner-2", + "title": "Banner 2", + "description": "Announcement and promo bars that sit above or inside page content.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/banner", + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/blocks/banner-2.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { Banner, BannerContainer } from \"@/components/ui/banner\"\nimport { buttonVariants } from \"@/components/ui/button\"\n\nfunction Banner2({\n className,\n title,\n description,\n buttons,\n ...props\n}: React.ComponentProps<\"aside\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n}) {\n return (\n \n \n
\n

{title}

\n

{description}

\n
\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n \n \n )\n}\n\nexport { Banner2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/banner/", + "categories": [ + "banner" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/banner.json b/public/r/react/styles/base-luma/banner.json new file mode 100644 index 000000000..97399bf89 --- /dev/null +++ b/public/r/react/styles/base-luma/banner.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "banner", + "title": "Banner", + "description": "A full-width container for important messages or announcements.", + "dependencies": [ + "class-variance-authority", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/banner.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\nimport { XIcon } from \"lucide-react\"\n\nconst bannerVariants = cva(\"py-2.5 relative flex items-center\", {\n variants: {\n variant: {\n default: \"bg-foreground text-background w-full\",\n floating:\n \"my-2 rounded-4xl bg-background shadow-md ring-1 ring-foreground/5 dark:ring-foreground/10 mx-auto w-[calc(100%-2*var(--gutter,--spacing(4)))] max-w-[calc(var(--container,var(--container-7xl))-2*var(--gutter,--spacing(4)))] overflow-hidden\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n})\n\nconst BannerContext = React.createContext<(() => void) | null>(null)\n\n// A closed banner stays closed for the browser session when it has a storage key.\nconst storageToken = (key: string) => `banner:${key}`\nconst subscribe = () => () => {}\n\nfunction Banner({\n className,\n variant = \"default\",\n storageKey,\n hidden,\n ...props\n}: React.ComponentProps<\"aside\"> &\n VariantProps & {\n storageKey?: string\n }) {\n const [closed, setClosed] = React.useState(false)\n // The server renders the banner; the browser hides one closed earlier.\n const stored = React.useSyncExternalStore(\n subscribe,\n () =>\n storageKey != null &&\n sessionStorage.getItem(storageToken(storageKey)) === \"hidden\",\n () => false\n )\n\n const close = React.useCallback(() => {\n setClosed(true)\n if (storageKey) sessionStorage.setItem(storageToken(storageKey), \"hidden\")\n }, [storageKey])\n\n return (\n \n \n )\n}\n\nfunction BannerContainer({\n className,\n children,\n showClose = true,\n closeLabel = \"Close\",\n ...props\n}: React.ComponentProps<\"div\"> & {\n showClose?: boolean\n closeLabel?: string\n}) {\n const close = React.useContext(BannerContext)\n return (\n \n {children}\n {showClose && (\n close?.()}\n className=\"rounded-full text-current/65 hover:text-current focus-visible:text-current focus-visible:ring-2 focus-visible:ring-ring/50 absolute top-1/2 right-4 z-20 inline-flex shrink-0 -translate-y-1/2 items-center justify-center transition-colors outline-none disabled:pointer-events-none disabled:opacity-50 in-[[data-variant=floating]]:right-5\"\n >\n \n {closeLabel}\n \n )}\n \n )\n}\n\nexport { Banner, BannerContainer, bannerVariants }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/banner/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/base.json b/public/r/react/styles/base-luma/base.json new file mode 100644 index 000000000..73ac3f84c --- /dev/null +++ b/public/r/react/styles/base-luma/base.json @@ -0,0 +1,143 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "extends": "none", + "name": "base", + "title": "Base", + "description": "Sets up a new project with `shadcn init`: style, registry, theme, class helper, and dependencies.", + "dependencies": [ + "class-variance-authority", + "cn", + "shadcn", + "tw-animate-css" + ], + "files": [ + { + "path": "src/lib/utils.ts", + "content": "export { cn } from \"cn\"\n", + "type": "registry:lib" + } + ], + "cssVars": { + "theme": { + "font-heading": "var(--font-sans)" + }, + "light": { + "background": "oklch(1 0 0)", + "foreground": "oklch(0.145 0 0)", + "card": "oklch(1 0 0)", + "card-foreground": "oklch(0.145 0 0)", + "popover": "oklch(1 0 0)", + "popover-foreground": "oklch(0.145 0 0)", + "primary": "oklch(0.5488 0.2498 261.783)", + "primary-foreground": "oklch(1 0 0)", + "secondary": "oklch(0.97 0 0)", + "secondary-foreground": "oklch(0.205 0 0)", + "muted": "oklch(0.97 0 0)", + "muted-foreground": "oklch(0.556 0 0)", + "accent": "oklch(0.97 0 0)", + "accent-foreground": "oklch(0.205 0 0)", + "destructive": "oklch(0.577 0.245 27.325)", + "border": "oklch(0.922 0 0)", + "input": "oklch(0.922 0 0)", + "ring": "oklch(0.708 0 0)", + "chart-1": "oklch(0.81 0.1 252)", + "chart-2": "oklch(0.62 0.19 260)", + "chart-3": "oklch(0.55 0.22 263)", + "chart-4": "oklch(0.49 0.22 264)", + "chart-5": "oklch(0.42 0.18 266)", + "sidebar": "oklch(0.985 0 0)", + "sidebar-foreground": "oklch(0.145 0 0)", + "sidebar-primary": "oklch(0.5488 0.2498 261.783)", + "sidebar-primary-foreground": "oklch(1 0 0)", + "sidebar-accent": "oklch(0.97 0 0)", + "sidebar-accent-foreground": "oklch(0.205 0 0)", + "sidebar-border": "oklch(0.922 0 0)", + "sidebar-ring": "oklch(0.708 0 0)", + "radius": "0.625rem", + "shadow-2xs": "0 1px 3px 0px hsl(0 0% 0% / 0.05)", + "shadow-xs": "0 1px 3px 0px hsl(0 0% 0% / 0.05)", + "shadow-sm": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1)", + "shadow": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1)", + "shadow-md": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1)", + "shadow-lg": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1)", + "shadow-xl": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1)", + "shadow-2xl": "0 1px 3px 0px hsl(0 0% 0% / 0.25)" + }, + "dark": { + "background": "oklch(0.145 0 0)", + "foreground": "oklch(0.985 0 0)", + "card": "oklch(0.205 0 0)", + "card-foreground": "oklch(0.985 0 0)", + "popover": "oklch(0.269 0 0)", + "popover-foreground": "oklch(0.985 0 0)", + "primary": "oklch(0.686 0.2105 41.139)", + "primary-foreground": "oklch(1 0 0)", + "secondary": "oklch(0.269 0 0)", + "secondary-foreground": "oklch(0.985 0 0)", + "muted": "oklch(0.269 0 0)", + "muted-foreground": "oklch(0.708 0 0)", + "accent": "oklch(0.371 0 0)", + "accent-foreground": "oklch(0.985 0 0)", + "destructive": "oklch(0.704 0.191 22.216)", + "border": "oklch(0.275 0 0)", + "input": "oklch(0.325 0 0)", + "ring": "oklch(0.556 0 0)", + "chart-1": "oklch(0.81 0.1 252)", + "chart-2": "oklch(0.62 0.19 260)", + "chart-3": "oklch(0.55 0.22 263)", + "chart-4": "oklch(0.49 0.22 264)", + "chart-5": "oklch(0.42 0.18 266)", + "sidebar": "oklch(0.205 0 0)", + "sidebar-foreground": "oklch(0.985 0 0)", + "sidebar-primary": "oklch(0.686 0.2105 41.139)", + "sidebar-primary-foreground": "oklch(1 0 0)", + "sidebar-accent": "oklch(0.269 0 0)", + "sidebar-accent-foreground": "oklch(0.985 0 0)", + "sidebar-border": "oklch(0.275 0 0)", + "sidebar-ring": "oklch(0.439 0 0)", + "shadow-2xs": "0 1px 3px 0px hsl(0 0% 0% / 0.05)", + "shadow-xs": "0 1px 3px 0px hsl(0 0% 0% / 0.05)", + "shadow-sm": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1)", + "shadow": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1)", + "shadow-md": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1)", + "shadow-lg": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1)", + "shadow-xl": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1)", + "shadow-2xl": "0 1px 3px 0px hsl(0 0% 0% / 0.25)" + } + }, + "css": { + "@import \"tw-animate-css\"": {}, + "@import \"shadcn/tailwind.css\"": {}, + "@layer base": { + "*": { + "@apply border-border outline-ring/50": {} + }, + "html": { + "@apply font-sans": {} + }, + "body": { + "@apply bg-background text-foreground": {} + } + }, + "@media (prefers-reduced-motion: reduce)": { + "*, ::before, ::after": { + "animation-duration": "0.01ms !important", + "animation-iteration-count": "1 !important", + "transition-duration": "0.01ms !important", + "scroll-behavior": "auto !important" + } + } + }, + "docs": "https://ui.full.dev/react/docs/installation/", + "type": "registry:base", + "config": { + "style": "base-luma", + "tailwind": { + "baseColor": "neutral" + }, + "iconLibrary": "lucide", + "registries": { + "@fulldev": "https://ui.full.dev/r/react/styles/{style}/{name}.json" + } + } +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/blocks-1.json b/public/r/react/styles/base-luma/blocks-1.json new file mode 100644 index 000000000..2ca16d584 --- /dev/null +++ b/public/r/react/styles/base-luma/blocks-1.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "blocks-1", + "title": "Blocks 1", + "dependencies": [ + "cn", + "lucide-react", + "simple-icons" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/section", + "@fulldev/typography" + ], + "files": [ + { + "path": "src/components/blocks/blocks-1.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\nimport {\n ArrowLeftIcon,\n ArrowRightIcon,\n CheckIcon,\n ChevronDownIcon,\n CopyIcon,\n ExternalLinkIcon,\n} from \"lucide-react\"\nimport { siClaude, siCursor, siMarkdown, type SimpleIcon } from \"simple-icons\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\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\n// Copies text and shows a check for a moment; a failed copy can be retried.\nfunction useCopy() {\n const [copied, setCopied] = React.useState(false)\n React.useEffect(() => {\n if (!copied) return\n const timeout = setTimeout(() => setCopied(false), 1200)\n return () => clearTimeout(timeout)\n }, [copied])\n const copy = (text: string) =>\n navigator.clipboard.writeText(text).then(\n () => setCopied(true),\n () => {}\n )\n return { copied, copy }\n}\n\nfunction BrandIcon({ icon }: { icon: SimpleIcon }) {\n return (\n \n \n \n )\n}\n\nfunction ChatGPTIcon() {\n return (\n \n \n \n )\n}\n\nfunction Blocks1({\n className,\n title,\n description,\n copyButton,\n markdownUrl,\n previousPage,\n nextPage,\n labels,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\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 assistantPrompt: string\n pagination: string\n }\n}) {\n const { copied, copy } = useCopy()\n const prompt = encodeURIComponent(labels.assistantPrompt)\n const openLinks = markdownUrl\n ? [\n {\n label: labels.openInMarkdown,\n href: markdownUrl,\n icon: ,\n },\n {\n label: labels.openInChatGPT,\n href: `https://chatgpt.com/?hints=search&q=${prompt}`,\n icon: ,\n },\n {\n label: labels.openInClaude,\n href: `https://claude.ai/new?q=${prompt}`,\n icon: ,\n },\n {\n label: labels.openInCursor,\n href: `https://cursor.com/link/prompt?text=${prompt}`,\n icon: ,\n },\n ]\n : []\n\n return (\n \n
\n
\n
\n \n {title}\n \n \n {description}\n \n
\n
\n {copyButton && (\n copy(copyButton.source)}\n >\n {copied ? (\n \n ) : (\n \n )}\n {labels.copyMarkdown}\n \n )}\n {openLinks.length > 0 && (\n \n \n {labels.openIn}\n \n \n \n \n {openLinks.map((link) => (\n \n }\n >\n {link.icon}\n {link.label}\n \n \n ))}\n \n \n \n )}\n
\n
\n\n } className=\"w-full max-w-none\">\n {children}\n \n\n {(previousPage || nextPage) && (\n \n {previousPage ? (\n \n \n \n {previousPage.title}\n \n \n ) : (\n
\n )}\n {nextPage ? (\n \n \n {nextPage.title}\n \n \n \n ) : (\n
\n )}\n \n )}\n
\n \n )\n}\n\nexport { Blocks1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/blocks/", + "categories": [ + "blocks" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/blocks.json b/public/r/react/styles/base-luma/blocks.json new file mode 100644 index 000000000..f090120cf --- /dev/null +++ b/public/r/react/styles/base-luma/blocks.json @@ -0,0 +1,92 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "blocks", + "title": "All blocks", + "description": "Installs every Fulldev UI React block.", + "registryDependencies": [ + "@fulldev/article-1", + "@fulldev/article-2", + "@fulldev/articles-1", + "@fulldev/articles-2", + "@fulldev/articles-3", + "@fulldev/articles-4", + "@fulldev/banner-1", + "@fulldev/banner-2", + "@fulldev/blocks-1", + "@fulldev/contact-1", + "@fulldev/contact-2", + "@fulldev/contact-3", + "@fulldev/content-1", + "@fulldev/content-2", + "@fulldev/content-3", + "@fulldev/content-4", + "@fulldev/cta-1", + "@fulldev/cta-2", + "@fulldev/cta-3", + "@fulldev/cta-4", + "@fulldev/cta-5", + "@fulldev/cta-6", + "@fulldev/cta-7", + "@fulldev/cta-8", + "@fulldev/doc-1", + "@fulldev/faqs-1", + "@fulldev/faqs-2", + "@fulldev/faqs-3", + "@fulldev/faqs-4", + "@fulldev/features-1", + "@fulldev/features-2", + "@fulldev/features-3", + "@fulldev/features-4", + "@fulldev/features-5", + "@fulldev/features-6", + "@fulldev/footer-1", + "@fulldev/footer-2", + "@fulldev/footer-3", + "@fulldev/header-1", + "@fulldev/header-2", + "@fulldev/header-3", + "@fulldev/header-4", + "@fulldev/header-5", + "@fulldev/hero-1", + "@fulldev/hero-10", + "@fulldev/hero-11", + "@fulldev/hero-12", + "@fulldev/hero-13", + "@fulldev/hero-2", + "@fulldev/hero-3", + "@fulldev/hero-4", + "@fulldev/hero-5", + "@fulldev/hero-6", + "@fulldev/hero-7", + "@fulldev/hero-8", + "@fulldev/hero-9", + "@fulldev/links-2", + "@fulldev/logos-1", + "@fulldev/logos-2", + "@fulldev/logos-3", + "@fulldev/pricing-1", + "@fulldev/pricing-2", + "@fulldev/pricing-3", + "@fulldev/product-1", + "@fulldev/products-1", + "@fulldev/products-2", + "@fulldev/products-3", + "@fulldev/products-4", + "@fulldev/products-5", + "@fulldev/reviews-1", + "@fulldev/reviews-2", + "@fulldev/reviews-3", + "@fulldev/reviews-4", + "@fulldev/reviews-5", + "@fulldev/services-1", + "@fulldev/services-2", + "@fulldev/services-3", + "@fulldev/services-4", + "@fulldev/services-5", + "@fulldev/services-6", + "@fulldev/services-7", + "@fulldev/sidebar-1" + ], + "docs": "https://ui.full.dev/react/blocks/", + "type": "registry:item" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/breadcrumb-examples.json b/public/r/react/styles/base-luma/breadcrumb-examples.json new file mode 100644 index 000000000..2f0b2d0e1 --- /dev/null +++ b/public/r/react/styles/base-luma/breadcrumb-examples.json @@ -0,0 +1,60 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "breadcrumb-examples", + "title": "Breadcrumb examples", + "description": "The examples from the shadcn/ui Breadcrumb docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/breadcrumb", + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/breadcrumb/breadcrumb-basic.tsx", + "content": "import {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\n\nexport function BreadcrumbBasic() {\n return (\n \n \n \n Home\n \n \n \n Components\n \n \n \n Breadcrumb\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-demo.tsx", + "content": "import {\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 DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function BreadcrumbDemo() {\n return (\n \n \n \n }>Home\n \n \n \n \n }\n >\n \n Toggle menu\n \n \n \n Documentation\n Themes\n GitHub\n \n \n \n \n \n \n }>Components\n \n \n \n Breadcrumb\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-dropdown.tsx", + "content": "import { ChevronDownIcon, DotIcon } from \"lucide-react\"\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function BreadcrumbDropdown() {\n return (\n \n \n \n }>Home\n \n \n \n \n \n \n }\n >\n Components\n \n \n \n \n Documentation\n Themes\n GitHub\n \n \n \n \n \n \n \n \n Breadcrumb\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-ellipsis.tsx", + "content": "import {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\n\nexport function BreadcrumbEllipsisDemo() {\n return (\n \n \n \n }>Home\n \n \n \n \n \n \n \n }\n >\n Components\n \n \n \n \n Breadcrumb\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-link.tsx", + "content": "import {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\n\nexport function BreadcrumbLinkDemo() {\n return (\n \n \n \n }>\n Home\n \n \n \n \n }>\n Components\n \n \n \n \n Breadcrumb\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-rtl.tsx", + "content": "\"use client\"\n\nimport { ChevronDownIcon, DotIcon } from \"lucide-react\"\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n home: \"Home\",\n components: \"Components\",\n documentation: \"Documentation\",\n themes: \"Themes\",\n github: \"GitHub\",\n breadcrumb: \"Breadcrumb\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n home: \"الرئيسية\",\n components: \"المكونات\",\n documentation: \"التوثيق\",\n themes: \"السمات\",\n github: \"جيت هاب\",\n breadcrumb: \"مسار التنقل\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n home: \"בית\",\n components: \"רכיבים\",\n documentation: \"תיעוד\",\n themes: \"ערכות נושא\",\n github: \"גיטהאב\",\n breadcrumb: \"פירורי לחם\",\n },\n },\n}\n\nexport function BreadcrumbRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n\n return (\n \n \n \n }>{t.home}\n \n \n \n \n \n \n }\n >\n {t.components}\n \n \n \n \n {t.documentation}\n {t.themes}\n {t.github}\n \n \n \n \n \n \n \n \n {t.breadcrumb}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-separator.tsx", + "content": "import { DotIcon } from \"lucide-react\"\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\n\nexport function BreadcrumbSeparatorDemo() {\n return (\n \n \n \n }>Home\n \n \n \n \n \n }>\n Components\n \n \n \n \n \n \n Breadcrumb\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/breadcrumb/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/breadcrumb.json b/public/r/react/styles/base-luma/breadcrumb.json new file mode 100644 index 000000000..6a43d5edb --- /dev/null +++ b/public/r/react/styles/base-luma/breadcrumb.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "breadcrumb", + "title": "Breadcrumb", + "description": "Displays the path to the current resource using a hierarchy of links.", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/breadcrumb.tsx", + "content": "import * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cn } from \"cn\"\nimport { ChevronRightIcon, MoreHorizontalIcon } from \"lucide-react\"\n\nfunction Breadcrumb({ className, ...props }: React.ComponentProps<\"nav\">) {\n return (\n \n )\n}\n\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<\"ol\">) {\n return (\n \n )\n}\n\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n \n )\n}\n\nfunction BreadcrumbLink({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"a\">) {\n return useRender({\n defaultTagName: \"a\",\n props: mergeProps<\"a\">(\n {\n className: cn(\"hover:text-foreground transition-colors\", className),\n },\n props\n ),\n render,\n state: {\n slot: \"breadcrumb-link\",\n },\n })\n}\n\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n \n )\n}\n\nfunction BreadcrumbSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n svg]:size-3.5\", className)}\n {...props}\n >\n {children ?? }\n \n )\n}\n\nfunction BreadcrumbEllipsis({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n svg]:size-4 flex items-center justify-center\",\n className\n )}\n {...props}\n >\n \n More\n \n )\n}\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/breadcrumb/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/bubble-examples.json b/public/r/react/styles/base-luma/bubble-examples.json new file mode 100644 index 000000000..d6e43dfda --- /dev/null +++ b/public/r/react/styles/base-luma/bubble-examples.json @@ -0,0 +1,74 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "bubble-examples", + "title": "Bubble examples", + "description": "The examples from the shadcn/ui Bubble docs.", + "dependencies": [ + "@streamdown/code", + "cn", + "lucide-react", + "sonner", + "streamdown" + ], + "registryDependencies": [ + "@fulldev/bubble", + "@fulldev/button", + "@fulldev/collapsible", + "@fulldev/popover", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/bubble/bubble-alignment.tsx", + "content": "import { Bubble, BubbleContent } from \"@/components/ui/bubble\"\n\nexport function BubbleAlignmentDemo() {\n return (\n
\n \n \n This bubble is aligned to the start. This is the default alignment.\n \n \n \n \n This bubble is aligned to the end. Use this for user messages.\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-collapsible.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Bubble, BubbleContent } from \"@/components/ui/bubble\"\nimport { Button } from \"@/components/ui/button\"\nimport { Collapsible, CollapsibleTrigger } from \"@/components/ui/collapsible\"\n\nconst text = `The accessibility review found two focus states that were visually too subtle in dark mode.\n\nI checked the dialog, menu, and drawer paths because each one renders focusable controls inside a layered surface.\n\nThe dialog and drawer are fine. The menu needs the hover and focus tokens split so keyboard focus stays visible when the pointer is not involved.\n\nI also recommend keeping the change in the style file instead of the primitive so the other themes can choose their own focus treatment later.`\n\nconst previewLength = 180\n\nexport function BubbleCollapsible() {\n const [open, setOpen] = React.useState(false)\n const isLong = text.length > previewLength\n const preview = `${text.slice(0, previewLength)}...`\n\n return (\n
\n \n How can I help you today?\n \n\n \n \n \n
{open || !isLong ? text : preview}
\n {isLong ? (\n \n }\n >\n {open ? \"Show less\" : \"Show more\"}\n \n \n ) : null}\n
\n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-demo.tsx", + "content": "import {\n Bubble,\n BubbleContent,\n BubbleGroup,\n BubbleReactions,\n} from \"@/components/ui/bubble\"\n\nexport function BubbleDemo() {\n return (\n
\n \n Hey there! what's up?\n \n \n \n Hey! Want to see chat bubbles?\n \n \n \n I can group messages, switch sides, and keep the whole thread easy\n to scan.\n \n \n 👍\n \n \n \n \n Sure. Hit me with your best demo.\n \n \n \n Yes. You are reading a demo that is demoing itself. Very meta. Very\n on-brand.\n \n \n 👍\n 🔥\n 👀\n +2\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-group-demo.tsx", + "content": "import {\n Bubble,\n BubbleContent,\n BubbleGroup,\n BubbleReactions,\n} from \"@/components/ui/bubble\"\n\nexport function BubbleGroupDemo() {\n return (\n
\n \n Can you tell me what's the issue?\n \n \n \n You tell me!\n \n \n It worked yesterday. You broke it!\n \n \n Find the bug and fix it.\n \n 👀\n \n \n \n \n \n Want me to diff yesterday's you against today's you?\n It's a bit embarrassing.\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-link-button.tsx", + "content": "\"use client\"\n\nimport { toast } from \"sonner\"\n\nimport { Bubble, BubbleContent, BubbleGroup } from \"@/components/ui/bubble\"\n\nexport function BubbleLinkButtonDemo() {\n return (\n
\n \n How can I help you today?\n \n \n \n toast(\"You clicked forgot password\")} />\n }\n >\n I forgot my password\n \n \n \n toast(\"You clicked help with subscription\")}\n />\n }\n >\n I need help with my subscription\n \n \n \n \n toast(\"You clicked something else. Talk to a human.\")\n }\n />\n }\n >\n Something else. Talk to a human.\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-popover.tsx", + "content": "import { InfoIcon } from \"lucide-react\"\n\nimport { Bubble, BubbleContent, BubbleReactions } from \"@/components/ui/bubble\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n\nexport function BubblePopoverDemo() {\n return (\n
\n \n Run the build script.\n \n \n Failed to run the command.\n \n \n \n }\n >\n \n \n \n \n \n Command failed with exit code 1\n \n \n ENOENT: no such file or directory, open pnpm-lock.yaml\n \n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-reactions.tsx", + "content": "\"use client\"\n\nimport { toast } from \"sonner\"\n\nimport { Bubble, BubbleContent, BubbleReactions } from \"@/components/ui/bubble\"\nimport { Button } from \"@/components/ui/button\"\n\nexport function BubbleReactionsDemo() {\n return (\n
\n \n \n I don't need tests, I know my code works.\n \n \n 👍\n 😮\n \n \n \n \n Bold. Fine I'll add some tests. I'll let you know when\n they're done.\n \n \n 👀\n 🚀\n +2\n \n \n \n \n Tests passed on the first try. All 142 of them. Looking good!\n \n \n 🎉\n 👏\n \n \n \n Are you sure I can run this command?\n \n toast.success(\"You clicked yes, running command...\")}\n >\n Yes, run it\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-tooltip.tsx", + "content": "import { CheckIcon } from \"lucide-react\"\n\nimport { Bubble, BubbleContent, BubbleReactions } from \"@/components/ui/bubble\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\n\nexport function BubbleTooltipDemo() {\n return (\n
\n \n Did you remove the stale route?\n \n \n Yes, removed it from the registry.\n \n \n }>\n \n \n Read on Jan 5, 2026 at 4:32 PM\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-variants.tsx", + "content": "import { Bubble, BubbleContent, BubbleReactions } from \"@/components/ui/bubble\"\nimport { Markdown } from \"@/components/markdown\"\n\nexport function BubbleVariantsDemo() {\n return (\n
\n \n This is the default primary bubble.\n \n \n This is the secondary variant.\n \n \n \n This one is muted. It uses a lower emphasis color for the chat bubble.\n \n \n 👍\n \n \n \n \n This one is tinted. The tint is a softer color derived from the\n primary color.\n \n \n \n We can also use an outlined variant.\n \n \n Or a destructive variant with a reaction.\n \n 🔥\n \n \n \n \n {`Ghost bubbles work for assistant text, **markdown**, and other content that should not be framed.\n\nThis is perfect for assistant messages that should not have a frame and can take the full width of the container. You can also render \\`code\\` in it.\n\nGhost bubbles are full width and can take the full width of the container.\n`}\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/markdown.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { code } from \"@streamdown/code\"\nimport { cn } from \"cn\"\nimport { Streamdown } from \"streamdown\"\n\nconst DEFAULT_PLUGINS = { code }\n\nfunction Markdown({\n className,\n plugins = DEFAULT_PLUGINS,\n controls = false,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nexport { Markdown }\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/bubble/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/bubble.json b/public/r/react/styles/base-luma/bubble.json new file mode 100644 index 000000000..3013bfd98 --- /dev/null +++ b/public/r/react/styles/base-luma/bubble.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "bubble", + "title": "Bubble", + "description": "Displays a chat message in a bubble, with grouping and reactions.", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/bubble.tsx", + "content": "import * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nfunction BubbleGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nconst bubbleVariants = cva(\n \"gap-1 data-[align=end]:self-end max-w-[80%] data-[variant=ghost]:max-w-full group-data-[align=end]/message:self-end group/bubble relative flex w-fit min-w-0 flex-col\",\n {\n variants: {\n variant: {\n default: \"*:data-[slot=bubble-content]:bg-primary *:data-[slot=bubble-content]:text-primary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-primary/80\",\n secondary: \"*:data-[slot=bubble-content]:bg-secondary *:data-[slot=bubble-content]:text-secondary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]\",\n muted: \"*:data-[slot=bubble-content]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--muted),var(--foreground)_5%)]\",\n tinted: \"*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]\",\n outline: \"*:data-[slot=bubble-content]:bg-background *:data-[slot=bubble-content]:border-border [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30\",\n ghost: \"*:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50 border-none\",\n destructive: \"*:data-[slot=bubble-content]:bg-destructive/10 dark:*:data-[slot=bubble-content]:bg-destructive/20 *:data-[slot=bubble-content]:text-destructive [&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/20 dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/30\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Bubble({\n variant = \"default\",\n align = \"start\",\n className,\n ...props\n}: React.ComponentProps<\"div\"> &\n VariantProps & {\n align?: \"start\" | \"end\"\n }) {\n return (\n \n )\n}\n\nfunction BubbleContent({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"div\">) {\n return useRender({\n defaultTagName: \"div\",\n props: mergeProps<\"div\">(\n {\n className: cn(\n \"rounded-3xl border border-transparent px-3.5 py-2.5 text-sm leading-relaxed [button,a]:outline-none [button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-3 [button,a]:focus-visible:ring-ring/30 group-data-[align=end]/bubble:self-end w-fit max-w-full min-w-0 overflow-hidden wrap-break-word [button]:text-left [button,a]:transition-colors\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"bubble-content\",\n },\n })\n}\n\nconst bubbleReactionsVariants = cva(\n \"rounded-full ring-3 ring-card bg-muted shrink-0 gap-1 px-1.5 py-0.5 has-[button]:p-0 text-sm absolute z-10 flex w-fit items-center justify-center\",\n {\n variants: {\n side: {\n top: \"top-0 -translate-y-3/4\",\n bottom: \"bottom-0 translate-y-3/4\",\n },\n align: {\n start: \"left-3\",\n end: \"right-3\",\n },\n },\n defaultVariants: {\n side: \"bottom\",\n align: \"end\",\n },\n }\n)\n\nfunction BubbleReactions({\n side = \"bottom\",\n align = \"end\",\n className,\n ...props\n}: React.ComponentProps<\"div\"> & {\n align?: \"start\" | \"end\"\n side?: \"top\" | \"bottom\"\n}) {\n return (\n \n )\n}\n\nexport { BubbleGroup, Bubble, BubbleContent, BubbleReactions }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/bubble/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/button-examples.json b/public/r/react/styles/base-luma/button-examples.json new file mode 100644 index 000000000..e9dd537a1 --- /dev/null +++ b/public/r/react/styles/base-luma/button-examples.json @@ -0,0 +1,95 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "button-examples", + "title": "Button examples", + "description": "The examples from the shadcn/ui Button docs.", + "dependencies": [ + "@tabler/icons-react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/select", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/button/button-default.tsx", + "content": "import { Button } from \"@/components/ui/button\"\n\nexport function ButtonDefault() {\n return \n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-demo.tsx", + "content": "import { ArrowUpIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nexport function ButtonDemo() {\n return (\n
\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-destructive.tsx", + "content": "import { Button } from \"@/components/ui/button\"\n\nexport function ButtonDestructive() {\n return \n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-ghost.tsx", + "content": "import { Button } from \"@/components/ui/button\"\n\nexport function ButtonGhost() {\n return \n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-icon.tsx", + "content": "import { CircleFadingArrowUpIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nexport function ButtonIcon() {\n return (\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-link.tsx", + "content": "import { Button } from \"@/components/ui/button\"\n\nexport function ButtonLink() {\n return \n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-outline.tsx", + "content": "import { Button } from \"@/components/ui/button\"\n\nexport function ButtonOutline() {\n return \n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-render.tsx", + "content": "import { buttonVariants } from \"@/components/ui/button\"\n\nexport function ButtonRender() {\n return (\n \n Login\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-rounded.tsx", + "content": "import { ArrowUpIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nexport function ButtonRounded() {\n return (\n
\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-rtl.tsx", + "content": "\"use client\"\n\nimport { ArrowRightIcon, PlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Spinner } from \"@/components/ui/spinner\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n button: \"Button\",\n submit: \"Submit\",\n delete: \"Delete\",\n loading: \"Loading\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n button: \"زر\",\n submit: \"إرسال\",\n delete: \"حذف\",\n loading: \"جاري التحميل\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n button: \"כפתור\",\n submit: \"שלח\",\n delete: \"מחק\",\n loading: \"טוען\",\n },\n },\n}\n\nexport function ButtonRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n
\n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-secondary.tsx", + "content": "import { Button } from \"@/components/ui/button\"\n\nexport function ButtonSecondary() {\n return \n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-size.tsx", + "content": "import { ArrowUpRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nexport function ButtonSize() {\n return (\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-spinner.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\nexport function ButtonLoading() {\n return (\n
\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-with-icon.tsx", + "content": "import { IconGitBranch, IconGitFork } from \"@tabler/icons-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nexport function ButtonWithIcon() {\n return (\n
\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/button/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/button-group-examples.json b/public/r/react/styles/base-luma/button-group-examples.json new file mode 100644 index 000000000..33d7a87d5 --- /dev/null +++ b/public/r/react/styles/base-luma/button-group-examples.json @@ -0,0 +1,92 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "button-group-examples", + "title": "Button Group examples", + "description": "The examples from the shadcn/ui Button Group docs.", + "dependencies": [ + "@tabler/icons-react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/button-group", + "@fulldev/dropdown-menu", + "@fulldev/field", + "@fulldev/input", + "@fulldev/input-group", + "@fulldev/popover", + "@fulldev/select", + "@fulldev/textarea", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/button-group/button-group-demo.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArchiveIcon,\n ArrowLeftIcon,\n CalendarPlusIcon,\n ClockIcon,\n ListFilterIcon,\n MailCheckIcon,\n MoreHorizontalIcon,\n TagIcon,\n Trash2Icon,\n} from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function ButtonGroupDemo() {\n const [label, setLabel] = React.useState(\"personal\")\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n }\n >\n \n \n \n \n \n \n Mark as Read\n \n \n \n Archive\n \n \n \n \n \n \n Snooze\n \n \n \n Add to Calendar\n \n \n \n Add to List\n \n \n \n \n Label As...\n \n \n \n \n Personal\n \n \n Work\n \n \n Other\n \n \n \n \n \n \n \n \n \n Trash\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-dropdown.tsx", + "content": "\"use client\"\n\nimport {\n AlertTriangleIcon,\n CheckIcon,\n ChevronDownIcon,\n CopyIcon,\n ShareIcon,\n TrashIcon,\n UserRoundXIcon,\n VolumeOffIcon,\n} from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function ButtonGroupDropdown() {\n return (\n \n \n \n }\n >\n \n \n \n \n \n \n Mute Conversation\n \n \n \n Mark as Read\n \n \n \n Report Conversation\n \n \n \n Block User\n \n \n \n Share Conversation\n \n \n \n Copy Conversation\n \n \n \n \n \n \n Delete Conversation\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-input-group.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { AudioLinesIcon, PlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\n\nexport function ButtonGroupInputGroup() {\n const [voiceEnabled, setVoiceEnabled] = React.useState(false)\n\n return (\n \n \n \n \n \n \n \n \n \n setVoiceEnabled(!voiceEnabled)}\n size=\"icon-xs\"\n data-active={voiceEnabled}\n className=\"data-[active=true]:bg-orange-100 data-[active=true]:text-orange-700 dark:data-[active=true]:bg-orange-800 dark:data-[active=true]:text-orange-100\"\n aria-pressed={voiceEnabled}\n />\n }\n >\n \n \n Voice Mode\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-input.tsx", + "content": "import { SearchIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function ButtonGroupInput() {\n return (\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-nested.tsx", + "content": "import { AudioLinesIcon, PlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\n\nexport function ButtonGroupNested() {\n return (\n \n \n \n \n \n \n \n \n }>\n \n \n Voice Mode\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-orientation.tsx", + "content": "import { MinusIcon, PlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\n\nexport function ButtonGroupOrientation() {\n return (\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-popover.tsx", + "content": "import { BotIcon, ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\nimport { Textarea } from \"@/components/ui/textarea\"\n\nexport function ButtonGroupPopover() {\n return (\n \n \n \n \n }\n >\n \n \n \n \n Start a new task with Copilot\n \n Describe your task in natural language.\n \n \n \n \n Task Description\n \n \n \n Copilot will open a pull request for review.\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArchiveIcon,\n ArrowLeftIcon,\n CalendarPlusIcon,\n ClockIcon,\n ListFilterIcon,\n MailCheckIcon,\n MoreHorizontalIcon,\n TagIcon,\n Trash2Icon,\n} from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n archive: \"Archive\",\n report: \"Report\",\n snooze: \"Snooze\",\n markAsRead: \"Mark as Read\",\n addToCalendar: \"Add to Calendar\",\n addToList: \"Add to List\",\n labelAs: \"Label As...\",\n personal: \"Personal\",\n work: \"Work\",\n other: \"Other\",\n trash: \"Trash\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n archive: \"أرشفة\",\n report: \"تقرير\",\n snooze: \"تأجيل\",\n markAsRead: \"وضع علامة كمقروء\",\n addToCalendar: \"إضافة إلى التقويم\",\n addToList: \"إضافة إلى القائمة\",\n labelAs: \"تصنيف كـ...\",\n personal: \"شخصي\",\n work: \"عمل\",\n other: \"آخر\",\n trash: \"سلة المهملات\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n archive: \"ארכיון\",\n report: \"דוח\",\n snooze: \"דחה\",\n markAsRead: \"סמן כנקרא\",\n addToCalendar: \"הוסף ליומן\",\n addToList: \"הוסף לרשימה\",\n labelAs: \"תייג כ...\",\n personal: \"אישי\",\n work: \"עבודה\",\n other: \"אחר\",\n trash: \"פח\",\n },\n },\n}\n\nexport function ButtonGroupRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n const [label, setLabel] = React.useState(\"personal\")\n\n return (\n
\n \n \n \n \n \n \n \n \n \n \n \n \n }\n >\n \n \n \n \n \n \n {t.markAsRead}\n \n \n \n {t.archive}\n \n \n \n \n \n \n {t.snooze}\n \n \n \n {t.addToCalendar}\n \n \n \n {t.addToList}\n \n \n \n \n {t.labelAs}\n \n \n \n \n {t.personal}\n \n \n {t.work}\n \n \n {t.other}\n \n \n \n \n \n \n \n \n \n {t.trash}\n \n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-select.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n} from \"@/components/ui/select\"\n\nconst CURRENCIES = [\n { label: \"US Dollar\", value: \"$\" },\n { label: \"Euro\", value: \"€\" },\n { label: \"British Pound\", value: \"£\" },\n]\n\nexport function ButtonGroupSelect() {\n const [currency, setCurrency] = React.useState(\"$\")\n\n return (\n \n \n setCurrency(value as string)}\n >\n {currency}\n \n \n {CURRENCIES.map((item) => (\n \n {item.value}{\" \"}\n {item.label}\n \n ))}\n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-separator.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport { ButtonGroup, ButtonGroupSeparator } from \"@/components/ui/button-group\"\n\nexport function ButtonGroupSeparatorDemo() {\n return (\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-size.tsx", + "content": "import { PlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\n\nexport function ButtonGroupSize() {\n return (\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-split.tsx", + "content": "import { IconPlus } from \"@tabler/icons-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { ButtonGroup, ButtonGroupSeparator } from \"@/components/ui/button-group\"\n\nexport function ButtonGroupSplit() {\n return (\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/button-group/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/button-group.json b/public/r/react/styles/base-luma/button-group.json new file mode 100644 index 000000000..0cc73a0c2 --- /dev/null +++ b/public/r/react/styles/base-luma/button-group.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "button-group", + "title": "Button Group", + "description": "Groups related controls with connected edges and consistent focus behavior.", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/ui/button-group.tsx", + "content": "import { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nimport { Separator } from \"@/components/ui/separator\"\n\nconst buttonGroupVariants = cva(\n \"has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-4xl has-[>[data-variant=outline]]:[&>input]:border-border has-[>[data-variant=outline]]:[&>input:focus-visible]:border-ring has-[>[data-variant=outline]]:*:data-[slot=input-group]:border-border has-[>[data-variant=outline]]:[&>[data-slot=input-group]:has(:focus-visible)]:border-ring has-[>[data-variant=outline]]:*:data-[slot=select-trigger]:border-border has-[>[data-variant=outline]]:[&>[data-slot=select-trigger]:focus-visible]:border-ring flex w-fit items-stretch *:focus-visible:relative *:focus-visible:z-10 [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1\",\n {\n variants: {\n orientation: {\n horizontal:\n \"[&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-4xl! *:data-slot:rounded-r-none [&>[data-slot]~[data-slot]]:rounded-l-none [&>[data-slot]~[data-slot]]:border-l-0\",\n vertical:\n \"[&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-4xl! flex-col *:data-slot:rounded-b-none [&>[data-slot]~[data-slot]]:rounded-t-none [&>[data-slot]~[data-slot]]:border-t-0\",\n },\n },\n defaultVariants: {\n orientation: \"horizontal\",\n },\n }\n)\n\nfunction ButtonGroup({\n className,\n orientation,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps) {\n return (\n \n )\n}\n\nfunction ButtonGroupText({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"div\">) {\n return useRender({\n defaultTagName: \"div\",\n props: mergeProps<\"div\">(\n {\n className: cn(\n \"bg-muted gap-2 rounded-4xl border px-2.5 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 flex items-center [&_svg]:pointer-events-none\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"button-group-text\",\n },\n })\n}\n\nfunction ButtonGroupSeparator({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nexport {\n ButtonGroup,\n ButtonGroupSeparator,\n ButtonGroupText,\n buttonGroupVariants,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/button-group/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/button.json b/public/r/react/styles/base-luma/button.json new file mode 100644 index 000000000..52759ed0a --- /dev/null +++ b/public/r/react/styles/base-luma/button.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "button", + "title": "Button", + "description": "Displays a button or a component that looks like a button.", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/button.tsx", + "content": "import { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nconst buttonVariants = cva(\n \"focus-visible:border-ring focus-visible:ring-ring/30 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-4xl border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 active:not-aria-[haspopup]:translate-y-px [&_svg:not([class*='size-'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-all outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/80\",\n outline: \"border-border bg-background dark:bg-transparent hover:bg-muted hover:text-foreground dark:hover:bg-input/30 aria-expanded:bg-muted aria-expanded:text-foreground\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost: \"hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground\",\n destructive: \"bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5\",\n xs: \"h-6 gap-1 px-2.5 text-xs has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n lg: \"h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3\",\n icon: \"size-9\",\n \"icon-xs\": \"size-6 [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps) {\n return (\n \n )\n}\n\nexport { Button, buttonVariants }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/button/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/calendar-examples.json b/public/r/react/styles/base-luma/calendar-examples.json new file mode 100644 index 000000000..1aa6e446f --- /dev/null +++ b/public/r/react/styles/base-luma/calendar-examples.json @@ -0,0 +1,86 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "calendar-examples", + "title": "Calendar examples", + "description": "The examples from the shadcn/ui Calendar docs.", + "dependencies": [ + "@daypicker/persian@10.0.2", + "@fontsource-variable/vazirmatn", + "cn", + "date-fns", + "lucide-react", + "react-day-picker" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/calendar", + "@fulldev/card", + "@fulldev/field", + "@fulldev/input-group", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/calendar/calendar-basic.tsx", + "content": "\"use client\"\n\nimport { Calendar } from \"@/components/ui/calendar\"\n\nexport function CalendarBasic() {\n return \n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-booked-dates.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/components/ui/calendar\"\nimport { Card, CardContent } from \"@/components/ui/card\"\n\nexport function CalendarBookedDates() {\n const [date, setDate] = React.useState(\n new Date(new Date().getFullYear(), 0, 6)\n )\n const bookedDates = Array.from(\n { length: 15 },\n (_, i) => new Date(new Date().getFullYear(), 0, 12 + i)\n )\n\n return (\n \n \n button]:line-through opacity-100\",\n }}\n />\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-caption.tsx", + "content": "\"use client\"\n\nimport { Calendar } from \"@/components/ui/calendar\"\n\nexport function CalendarCaption() {\n return (\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-custom-days.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { addDays } from \"date-fns\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar, CalendarDayButton } from \"@/components/ui/calendar\"\nimport { Card, CardContent } from \"@/components/ui/card\"\n\nexport function CalendarCustomDays() {\n const [range, setRange] = React.useState({\n from: new Date(new Date().getFullYear(), 11, 8),\n to: addDays(new Date(new Date().getFullYear(), 11, 8), 10),\n })\n\n return (\n \n \n {\n return date.toLocaleString(\"default\", { month: \"long\" })\n },\n }}\n components={{\n DayButton: ({ children, modifiers, day, ...props }) => {\n const isWeekend =\n day.date.getDay() === 0 || day.date.getDay() === 6\n\n return (\n \n {children}\n {!modifiers.outside && (\n {isWeekend ? \"$120\" : \"$100\"}\n )}\n \n )\n },\n }}\n />\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-demo.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/components/ui/calendar\"\n\nexport function CalendarDemo() {\n const [date, setDate] = React.useState(new Date())\n\n return (\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-hijri.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport \"@fontsource-variable/vazirmatn\"\n\nimport { DayPicker } from \"@daypicker/persian\"\nimport { cn } from \"cn\"\nimport {\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n} from \"lucide-react\"\nimport { getDefaultClassNames, type DayButton } from \"react-day-picker\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\n\nexport function CalendarHijri() {\n const [date, setDate] = React.useState(\n new Date(2025, 5, 12)\n )\n\n return (\n
\n \n
\n )\n}\n\n// ----------------------------------------------------------------------------\n// The code below is for this example only.\n// For your own calendar, you would edit the calendar.tsx component directly.\n// ----------------------------------------------------------------------------\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n captionLayout = \"label\",\n buttonVariant = \"ghost\",\n formatters,\n components,\n ...props\n}: React.ComponentProps & {\n buttonVariant?: React.ComponentProps[\"variant\"]\n}) {\n const defaultClassNames = getDefaultClassNames()\n\n return (\n svg]:rotate-180`,\n String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n className\n )}\n captionLayout={captionLayout}\n formatters={{\n formatMonthDropdown: (date) =>\n date.toLocaleString(\"default\", { month: \"short\" }),\n ...formatters,\n }}\n classNames={{\n root: cn(\"w-fit\", defaultClassNames.root),\n months: cn(\n \"relative flex flex-col gap-4 md:flex-row\",\n defaultClassNames.months\n ),\n month: cn(\"flex w-full flex-col gap-4\", defaultClassNames.month),\n nav: cn(\n \"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1\",\n defaultClassNames.nav\n ),\n button_previous: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n defaultClassNames.button_previous\n ),\n button_next: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n defaultClassNames.button_next\n ),\n month_caption: cn(\n \"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)\",\n defaultClassNames.month_caption\n ),\n dropdowns: cn(\n \"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium\",\n defaultClassNames.dropdowns\n ),\n dropdown_root: cn(\n \"relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50\",\n defaultClassNames.dropdown_root\n ),\n dropdown: cn(\"absolute inset-0 opacity-0\", defaultClassNames.dropdown),\n caption_label: cn(\n \"font-medium select-none\",\n captionLayout === \"label\"\n ? \"text-sm\"\n : \"flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground\",\n defaultClassNames.caption_label\n ),\n month_grid: cn(\"w-full border-collapse\", defaultClassNames.month_grid),\n weekdays: cn(\"flex\", defaultClassNames.weekdays),\n weekday: cn(\n \"flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none\",\n defaultClassNames.weekday\n ),\n week: cn(\"mt-2 flex w-full\", defaultClassNames.week),\n week_number_header: cn(\n \"w-(--cell-size) select-none\",\n defaultClassNames.week_number_header\n ),\n week_number: cn(\n \"text-[0.8rem] text-muted-foreground select-none\",\n defaultClassNames.week_number\n ),\n day: cn(\n \"group/day relative aspect-square h-full w-full p-0 text-center select-none [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md\",\n defaultClassNames.day\n ),\n range_start: cn(\n \"rounded-l-md bg-accent\",\n defaultClassNames.range_start\n ),\n range_middle: cn(\"rounded-none\", defaultClassNames.range_middle),\n range_end: cn(\"rounded-r-md bg-accent\", defaultClassNames.range_end),\n today: cn(\n \"rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none\",\n defaultClassNames.today\n ),\n outside: cn(\n \"text-muted-foreground aria-selected:text-muted-foreground\",\n defaultClassNames.outside\n ),\n disabled: cn(\n \"text-muted-foreground opacity-50\",\n defaultClassNames.disabled\n ),\n hidden: cn(\"invisible\", defaultClassNames.hidden),\n ...classNames,\n }}\n components={{\n Root: ({ className, rootRef, ...props }) => {\n return (\n \n )\n },\n Chevron: ({ className, orientation, ...props }) => {\n if (orientation === \"left\") {\n return (\n \n )\n }\n\n if (orientation === \"right\") {\n return (\n \n )\n }\n\n return (\n \n )\n },\n DayButton: CalendarDayButton,\n WeekNumber: ({ children, ...props }) => {\n return (\n \n
\n {children}\n
\n \n )\n },\n ...components,\n }}\n {...props}\n />\n )\n}\n\nfunction CalendarDayButton({\n className,\n day,\n modifiers,\n ...props\n}: React.ComponentProps) {\n const defaultClassNames = getDefaultClassNames()\n\n const ref = React.useRef(null)\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus()\n }, [modifiers.focused])\n\n return (\n span]:text-xs [&>span]:opacity-70\",\n defaultClassNames.day,\n className\n )}\n {...props}\n />\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-presets.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { addDays } from \"date-fns\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Calendar } from \"@/components/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/components/ui/card\"\n\nexport function CalendarWithPresets() {\n const [date, setDate] = React.useState(\n new Date(new Date().getFullYear(), 1, 12)\n )\n const [currentMonth, setCurrentMonth] = React.useState(\n new Date(new Date().getFullYear(), new Date().getMonth(), 1)\n )\n\n return (\n \n \n \n \n \n {[\n { label: \"Today\", value: 0 },\n { label: \"Tomorrow\", value: 1 },\n { label: \"In 3 days\", value: 3 },\n { label: \"In a week\", value: 7 },\n { label: \"In 2 weeks\", value: 14 },\n ].map((preset) => (\n {\n const newDate = addDays(new Date(), preset.value)\n setDate(newDate)\n setCurrentMonth(\n new Date(newDate.getFullYear(), newDate.getMonth(), 1)\n )\n }}\n >\n {preset.label}\n \n ))}\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-range.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { addDays } from \"date-fns\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/components/ui/calendar\"\nimport { Card, CardContent } from \"@/components/ui/card\"\n\nexport function CalendarRange() {\n const [dateRange, setDateRange] = React.useState({\n from: new Date(new Date().getFullYear(), 0, 12),\n to: addDays(new Date(new Date().getFullYear(), 0, 12), 30),\n })\n\n return (\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { arSA, he } from \"react-day-picker/locale\"\n\nimport { Calendar } from \"@/components/ui/calendar\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {},\n },\n ar: {\n dir: \"rtl\",\n values: {},\n },\n he: {\n dir: \"rtl\",\n values: {},\n },\n}\n\nconst locales = {\n ar: arSA,\n he: he,\n} as const\n\nexport function CalendarRtl() {\n const { dir, language } = useTranslation(translations, \"ar\")\n const [date, setDate] = React.useState(new Date())\n\n return (\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-time.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Clock2Icon } from \"lucide-react\"\n\nimport { Calendar } from \"@/components/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/components/ui/card\"\nimport { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n\nexport function CalendarWithTime() {\n const [date, setDate] = React.useState(\n new Date(new Date().getFullYear(), new Date().getMonth(), 12)\n )\n\n return (\n \n \n \n \n \n \n \n Start Time\n \n \n \n \n \n \n \n \n End Time\n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-week-numbers.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/components/ui/calendar\"\nimport { Card, CardContent } from \"@/components/ui/card\"\n\nexport function CalendarWeekNumbers() {\n const [date, setDate] = React.useState(\n new Date(new Date().getFullYear(), 0, 12)\n )\n\n return (\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/calendar/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/calendar.json b/public/r/react/styles/base-luma/calendar.json new file mode 100644 index 000000000..0ed07c3b6 --- /dev/null +++ b/public/r/react/styles/base-luma/calendar.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "calendar", + "title": "Calendar", + "description": "A calendar for picking a date, several dates, or a range.", + "dependencies": [ + "cn", + "lucide-react", + "react-day-picker" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/calendar.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\nimport {\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n} from \"lucide-react\"\nimport {\n DayPicker,\n getDefaultClassNames,\n type DayButton,\n type Locale,\n} from \"react-day-picker\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n captionLayout = \"label\",\n buttonVariant = \"ghost\",\n locale,\n formatters,\n components,\n ...props\n}: React.ComponentProps & {\n buttonVariant?: React.ComponentProps[\"variant\"]\n}) {\n const defaultClassNames = getDefaultClassNames()\n\n return (\n svg]:rotate-180`,\n String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n className\n )}\n captionLayout={captionLayout}\n locale={locale}\n formatters={{\n formatMonthDropdown: (date) =>\n date.toLocaleString(locale?.code, { month: \"short\" }),\n ...formatters,\n }}\n classNames={{\n root: cn(\"w-fit\", defaultClassNames.root),\n months: cn(\n \"relative flex flex-col gap-4 md:flex-row\",\n defaultClassNames.months\n ),\n month: cn(\"flex w-full flex-col gap-4\", defaultClassNames.month),\n nav: cn(\n \"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1\",\n defaultClassNames.nav\n ),\n button_previous: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n defaultClassNames.button_previous\n ),\n button_next: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n defaultClassNames.button_next\n ),\n month_caption: cn(\n \"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)\",\n defaultClassNames.month_caption\n ),\n dropdowns: cn(\n \"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium\",\n defaultClassNames.dropdowns\n ),\n dropdown_root: cn(\n \"relative rounded-(--cell-radius)\",\n defaultClassNames.dropdown_root\n ),\n dropdown: cn(\n \"absolute inset-0 bg-popover opacity-0\",\n defaultClassNames.dropdown\n ),\n caption_label: cn(\n \"font-medium select-none\",\n captionLayout === \"label\"\n ? \"text-sm\"\n : \"flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground\",\n defaultClassNames.caption_label\n ),\n month_grid: cn(\"w-full border-collapse\", defaultClassNames.month_grid),\n weekdays: cn(\"flex\", defaultClassNames.weekdays),\n weekday: cn(\n \"flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal text-muted-foreground select-none\",\n defaultClassNames.weekday\n ),\n week: cn(\"mt-2 flex w-full\", defaultClassNames.week),\n week_number_header: cn(\n \"w-(--cell-size) select-none\",\n defaultClassNames.week_number_header\n ),\n week_number: cn(\n \"text-[0.8rem] text-muted-foreground select-none\",\n defaultClassNames.week_number\n ),\n day: cn(\n \"group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)\",\n props.showWeekNumber\n ? \"[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)\"\n : \"[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)\",\n defaultClassNames.day\n ),\n range_start: cn(\n \"relative isolate z-0 rounded-l-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:right-0 after:w-4 after:bg-muted\",\n defaultClassNames.range_start\n ),\n range_middle: cn(\"rounded-none\", defaultClassNames.range_middle),\n range_end: cn(\n \"relative isolate z-0 rounded-r-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:left-0 after:w-4 after:bg-muted\",\n defaultClassNames.range_end\n ),\n today: cn(\n \"rounded-(--cell-radius) bg-muted text-foreground data-[selected=true]:rounded-none\",\n defaultClassNames.today\n ),\n outside: cn(\n \"text-muted-foreground aria-selected:text-muted-foreground\",\n defaultClassNames.outside\n ),\n disabled: cn(\n \"text-muted-foreground opacity-50\",\n defaultClassNames.disabled\n ),\n hidden: cn(\"invisible\", defaultClassNames.hidden),\n ...classNames,\n }}\n components={{\n Root: ({ className, rootRef, ...props }) => {\n return (\n \n )\n },\n Chevron: ({ className, orientation, ...props }) => {\n if (orientation === \"left\") {\n return (\n \n )\n }\n\n if (orientation === \"right\") {\n return (\n \n )\n }\n\n return (\n \n )\n },\n DayButton: ({ ...props }) => (\n \n ),\n WeekNumber: ({ children, ...props }) => {\n return (\n \n
\n {children}\n
\n \n )\n },\n ...components,\n }}\n {...props}\n />\n )\n}\n\nfunction CalendarDayButton({\n className,\n day,\n modifiers,\n locale,\n ...props\n}: React.ComponentProps & { locale?: Partial }) {\n const defaultClassNames = getDefaultClassNames()\n\n const ref = React.useRef(null)\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus()\n }, [modifiers.focused])\n\n return (\n span]:text-xs [&>span]:opacity-70\",\n defaultClassNames.day,\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Calendar, CalendarDayButton }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/calendar/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/card-examples.json b/public/r/react/styles/base-luma/card-examples.json new file mode 100644 index 000000000..c6dbd1874 --- /dev/null +++ b/public/r/react/styles/base-luma/card-examples.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "card-examples", + "title": "Card examples", + "description": "The examples from the shadcn/ui Card docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/card", + "@fulldev/input", + "@fulldev/label", + "@fulldev/select", + "@fulldev/toggle-group" + ], + "files": [ + { + "path": "src/components/examples/card/card-demo.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Input } from \"@/components/ui/input\"\nimport { Label } from \"@/components/ui/label\"\n\nexport function CardDemo() {\n return (\n \n \n Login to your account\n \n Enter your email below to login to your account\n \n \n \n \n \n \n
\n
\n
\n \n \n
\n
\n
\n \n \n Forgot your password?\n \n
\n \n
\n
\n
\n
\n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/card/card-edge-to-edge.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\n\nexport function CardEdgeToEdge() {\n return (\n \n \n Terms of Service\n \n Review the terms before accepting the agreement.\n \n \n \n
\n

\n These terms govern your use of the workspace, including access to\n shared documents, project files, and collaboration tools.\n

\n

\n You are responsible for the content you upload and for ensuring that\n your team has the appropriate permissions to view or edit it.\n

\n

\n We may update features or limits as the service evolves. When those\n changes materially affect your workflow, we will notify your\n workspace administrators.\n

\n

\n By continuing, you agree to keep your account credentials secure and\n to follow your organization's acceptable use policies.\n

\n
\n
\n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/card/card-image.tsx", + "content": "import { Badge } from \"@/components/ui/badge\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\n\nexport function CardImage() {\n return (\n \n
\n \n \n \n Featured\n \n Design systems meetup\n \n A practical talk on component APIs, accessibility, and shipping\n faster.\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/card/card-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Input } from \"@/components/ui/input\"\nimport { Label } from \"@/components/ui/label\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n title: \"Login to your account\",\n description: \"Enter your email below to login to your account\",\n signUp: \"Sign Up\",\n email: \"Email\",\n emailPlaceholder: \"m@example.com\",\n password: \"Password\",\n forgotPassword: \"Forgot your password?\",\n login: \"Login\",\n loginWithGoogle: \"Login with Google\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n title: \"تسجيل الدخول إلى حسابك\",\n description: \"أدخل بريدك الإلكتروني أدناه لتسجيل الدخول إلى حسابك\",\n signUp: \"إنشاء حساب\",\n email: \"البريد الإلكتروني\",\n emailPlaceholder: \"m@example.com\",\n password: \"كلمة المرور\",\n forgotPassword: \"نسيت كلمة المرور؟\",\n login: \"تسجيل الدخول\",\n loginWithGoogle: \"تسجيل الدخول باستخدام Google\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n title: \"התחבר לחשבון שלך\",\n description: \"הזן את האימייל שלך למטה כדי להתחבר לחשבון שלך\",\n signUp: \"הירשם\",\n email: \"אימייל\",\n emailPlaceholder: \"m@example.com\",\n password: \"סיסמה\",\n forgotPassword: \"שכחת את הסיסמה?\",\n login: \"התחבר\",\n loginWithGoogle: \"התחבר עם Google\",\n },\n },\n}\n\nexport function CardRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n \n \n {t.title}\n {t.description}\n \n \n \n \n \n
\n
\n
\n \n \n
\n
\n
\n \n \n {t.forgotPassword}\n \n
\n \n
\n
\n
\n
\n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/card/card-small.tsx", + "content": "import { ChevronRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\n\nexport function CardSmall() {\n const featureName = \"Scheduled reports\"\n\n return (\n \n \n {featureName}\n \n Weekly snapshots. No more manual exports.\n \n \n \n
    \n
  • \n \n Choose a schedule (daily, or weekly).\n
  • \n
  • \n \n Send to channels or specific teammates.\n
  • \n
  • \n \n Include charts, tables, and key metrics.\n
  • \n
\n
\n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/card/card-spacing.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Input } from \"@/components/ui/input\"\nimport { Label } from \"@/components/ui/label\"\nimport { ToggleGroup, ToggleGroupItem } from \"@/components/ui/toggle-group\"\n\nconst spacingOptions = [\n {\n className: \"[--card-spacing:--spacing(4)]\",\n label: \"16px\",\n value: \"4\",\n },\n {\n className: \"[--card-spacing:--spacing(5)]\",\n label: \"20px\",\n value: \"5\",\n },\n {\n className: \"[--card-spacing:--spacing(6)]\",\n label: \"24px\",\n value: \"6\",\n },\n {\n className: \"[--card-spacing:--spacing(8)]\",\n label: \"32px\",\n value: \"8\",\n },\n]\n\nexport function CardSpacing() {\n const [spacing, setSpacing] = React.useState(\"4\")\n const selectedSpacing = spacingOptions.find(\n (option) => option.value === spacing\n )\n\n return (\n
\n {\n if (value[0]) {\n setSpacing(value[0])\n }\n }}\n variant=\"outline\"\n size=\"sm\"\n className=\"justify-center\"\n >\n {spacingOptions.map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n Login to your account\n \n Enter your email below to login to your account\n \n \n \n \n \n \n
\n
\n
\n \n \n
\n
\n
\n \n \n Forgot your password?\n \n
\n \n
\n
\n
\n
\n \n \n \n \n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/card/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/card.json b/public/r/react/styles/base-luma/card.json new file mode 100644 index 000000000..e1f31c04f --- /dev/null +++ b/public/r/react/styles/base-luma/card.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "card", + "title": "Card", + "description": "Displays a card with header, content, and footer.", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/card.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nfunction Card({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n return (\n img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(4)] *:[img:first-child]:rounded-t-4xl *:[img:last-child]:rounded-b-4xl group/card flex flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/card/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/carousel-examples.json b/public/r/react/styles/base-luma/carousel-examples.json new file mode 100644 index 000000000..05846ddfa --- /dev/null +++ b/public/r/react/styles/base-luma/carousel-examples.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "carousel-examples", + "title": "Carousel examples", + "description": "The examples from the shadcn/ui Carousel docs.", + "dependencies": [ + "cn", + "embla-carousel-autoplay@8.6.0" + ], + "registryDependencies": [ + "@fulldev/card", + "@fulldev/carousel", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/carousel/carousel-api.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n type CarouselApi,\n} from \"@/components/ui/carousel\"\n\nexport function CarouselDApiDemo() {\n const [api, setApi] = React.useState()\n const [current, setCurrent] = React.useState(0)\n const [count, setCount] = React.useState(0)\n\n React.useEffect(() => {\n if (!api) {\n return\n }\n\n setCount(api.scrollSnapList().length)\n setCurrent(api.selectedScrollSnap() + 1)\n\n api.on(\"select\", () => {\n setCurrent(api.selectedScrollSnap() + 1)\n })\n }, [api])\n\n return (\n
\n \n \n {Array.from({ length: 5 }).map((_, index) => (\n \n \n \n {index + 1}\n \n \n \n ))}\n \n \n \n \n
\n Slide {current} of {count}\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-demo.tsx", + "content": "import * as React from \"react\"\n\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\"\n\nexport function CarouselDemo() {\n return (\n \n \n {Array.from({ length: 5 }).map((_, index) => (\n \n
\n \n \n {index + 1}\n \n \n
\n
\n ))}\n
\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-orientation.tsx", + "content": "import * as React from \"react\"\n\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\"\n\nexport function CarouselOrientation() {\n return (\n \n \n {Array.from({ length: 5 }).map((_, index) => (\n \n
\n \n \n {index + 1}\n \n \n
\n
\n ))}\n
\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-plugin.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport Autoplay from \"embla-carousel-autoplay\"\n\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\"\n\nexport function CarouselPlugin() {\n const plugin = React.useRef(\n Autoplay({ delay: 2000, stopOnInteraction: true })\n )\n\n return (\n \n \n {Array.from({ length: 5 }).map((_, index) => (\n \n
\n \n \n {index + 1}\n \n \n
\n
\n ))}\n
\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {},\n },\n ar: {\n dir: \"rtl\",\n values: {},\n },\n he: {\n dir: \"rtl\",\n values: {},\n },\n}\n\nfunction toArabicNumerals(num: number): string {\n const arabicNumerals = [\"٠\", \"١\", \"٢\", \"٣\", \"٤\", \"٥\", \"٦\", \"٧\", \"٨\", \"٩\"]\n return num\n .toString()\n .split(\"\")\n .map((digit) => arabicNumerals[parseInt(digit, 10)])\n .join(\"\")\n}\n\nexport function CarouselRtl() {\n const { dir, language } = useTranslation(translations, \"ar\")\n\n const formatNumber = (num: number): string => {\n if (language === \"ar\") {\n return toArabicNumerals(num)\n }\n return num.toString()\n }\n\n return (\n \n \n {Array.from({ length: 5 }).map((_, index) => (\n \n
\n \n \n \n {formatNumber(index + 1)}\n \n \n \n
\n
\n ))}\n
\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-size.tsx", + "content": "import * as React from \"react\"\n\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\"\n\nexport function CarouselSize() {\n return (\n \n \n {Array.from({ length: 5 }).map((_, index) => (\n \n
\n \n \n {index + 1}\n \n \n
\n
\n ))}\n
\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-spacing.tsx", + "content": "import * as React from \"react\"\n\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\"\n\nexport function CarouselSpacing() {\n return (\n \n \n {Array.from({ length: 5 }).map((_, index) => (\n \n
\n \n \n {index + 1}\n \n \n
\n
\n ))}\n
\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/carousel/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/carousel.json b/public/r/react/styles/base-luma/carousel.json new file mode 100644 index 000000000..a1cc92f86 --- /dev/null +++ b/public/r/react/styles/base-luma/carousel.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "carousel", + "title": "Carousel", + "description": "A carousel with motion, swipe and responsive slides built using Embla.", + "dependencies": [ + "cn", + "embla-carousel-react@8.6.0", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/carousel.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\nimport useEmblaCarousel, {\n type UseEmblaCarouselType,\n} from \"embla-carousel-react\"\nimport { ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\ntype CarouselApi = UseEmblaCarouselType[1]\ntype UseCarouselParameters = Parameters\ntype CarouselOptions = UseCarouselParameters[0]\ntype CarouselPlugin = UseCarouselParameters[1]\n\ntype CarouselProps = {\n opts?: CarouselOptions\n plugins?: CarouselPlugin\n orientation?: \"horizontal\" | \"vertical\"\n setApi?: (api: CarouselApi) => void\n}\n\ntype CarouselContextProps = {\n carouselRef: ReturnType[0]\n api: ReturnType[1]\n scrollPrev: () => void\n scrollNext: () => void\n canScrollPrev: boolean\n canScrollNext: boolean\n} & CarouselProps\n\nconst CarouselContext = React.createContext(null)\n\nfunction useCarousel() {\n const context = React.useContext(CarouselContext)\n\n if (!context) {\n throw new Error(\"useCarousel must be used within a \")\n }\n\n return context\n}\n\nfunction Carousel({\n orientation = \"horizontal\",\n opts,\n setApi,\n plugins,\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & CarouselProps) {\n const [carouselRef, api] = useEmblaCarousel(\n {\n ...opts,\n axis: orientation === \"horizontal\" ? \"x\" : \"y\",\n },\n plugins\n )\n const [canScrollPrev, setCanScrollPrev] = React.useState(false)\n const [canScrollNext, setCanScrollNext] = React.useState(false)\n\n const onSelect = React.useCallback((api: CarouselApi) => {\n if (!api) return\n setCanScrollPrev(api.canScrollPrev())\n setCanScrollNext(api.canScrollNext())\n }, [])\n\n const scrollPrev = React.useCallback(() => {\n api?.scrollPrev()\n }, [api])\n\n const scrollNext = React.useCallback(() => {\n api?.scrollNext()\n }, [api])\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === \"ArrowLeft\") {\n event.preventDefault()\n scrollPrev()\n } else if (event.key === \"ArrowRight\") {\n event.preventDefault()\n scrollNext()\n }\n },\n [scrollPrev, scrollNext]\n )\n\n React.useEffect(() => {\n if (!api || !setApi) return\n setApi(api)\n }, [api, setApi])\n\n React.useEffect(() => {\n if (!api) return\n onSelect(api)\n api.on(\"reInit\", onSelect)\n api.on(\"select\", onSelect)\n\n return () => {\n api?.off(\"select\", onSelect)\n }\n }, [api, onSelect])\n\n return (\n \n \n {children}\n
\n \n )\n}\n\nfunction CarouselContent({ className, ...props }: React.ComponentProps<\"div\">) {\n const { carouselRef, orientation } = useCarousel()\n\n return (\n \n \n
\n )\n}\n\nfunction CarouselItem({ className, ...props }: React.ComponentProps<\"div\">) {\n const { orientation } = useCarousel()\n\n return (\n \n )\n}\n\nfunction CarouselPrevious({\n className,\n variant = \"outline\",\n size = \"icon-sm\",\n ...props\n}: React.ComponentProps) {\n const { orientation, scrollPrev, canScrollPrev } = useCarousel()\n\n return (\n \n \n Previous slide\n \n )\n}\n\nfunction CarouselNext({\n className,\n variant = \"outline\",\n size = \"icon-sm\",\n ...props\n}: React.ComponentProps) {\n const { orientation, scrollNext, canScrollNext } = useCarousel()\n\n return (\n \n \n Next slide\n \n )\n}\n\nexport {\n type CarouselApi,\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselPrevious,\n CarouselNext,\n useCarousel,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/carousel/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/chart-examples.json b/public/r/react/styles/base-luma/chart-examples.json new file mode 100644 index 000000000..aa8858343 --- /dev/null +++ b/public/r/react/styles/base-luma/chart-examples.json @@ -0,0 +1,64 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "chart-examples", + "title": "Chart examples", + "description": "The examples from the shadcn/ui Chart docs.", + "dependencies": [ + "cn", + "recharts@3.8.0" + ], + "registryDependencies": [ + "@fulldev/card", + "@fulldev/chart", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/chart/chart-demo.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Bar, BarChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n type ChartConfig,\n} from \"@/components/ui/chart\"\n\nexport const description = \"An interactive bar chart\"\n\nconst chartData = [\n { date: \"2024-04-01\", desktop: 222, mobile: 150 },\n { date: \"2024-04-02\", desktop: 97, mobile: 180 },\n { date: \"2024-04-03\", desktop: 167, mobile: 120 },\n { date: \"2024-04-04\", desktop: 242, mobile: 260 },\n { date: \"2024-04-05\", desktop: 373, mobile: 290 },\n { date: \"2024-04-06\", desktop: 301, mobile: 340 },\n { date: \"2024-04-07\", desktop: 245, mobile: 180 },\n { date: \"2024-04-08\", desktop: 409, mobile: 320 },\n { date: \"2024-04-09\", desktop: 59, mobile: 110 },\n { date: \"2024-04-10\", desktop: 261, mobile: 190 },\n { date: \"2024-04-11\", desktop: 327, mobile: 350 },\n { date: \"2024-04-12\", desktop: 292, mobile: 210 },\n { date: \"2024-04-13\", desktop: 342, mobile: 380 },\n { date: \"2024-04-14\", desktop: 137, mobile: 220 },\n { date: \"2024-04-15\", desktop: 120, mobile: 170 },\n { date: \"2024-04-16\", desktop: 138, mobile: 190 },\n { date: \"2024-04-17\", desktop: 446, mobile: 360 },\n { date: \"2024-04-18\", desktop: 364, mobile: 410 },\n { date: \"2024-04-19\", desktop: 243, mobile: 180 },\n { date: \"2024-04-20\", desktop: 89, mobile: 150 },\n { date: \"2024-04-21\", desktop: 137, mobile: 200 },\n { date: \"2024-04-22\", desktop: 224, mobile: 170 },\n { date: \"2024-04-23\", desktop: 138, mobile: 230 },\n { date: \"2024-04-24\", desktop: 387, mobile: 290 },\n { date: \"2024-04-25\", desktop: 215, mobile: 250 },\n { date: \"2024-04-26\", desktop: 75, mobile: 130 },\n { date: \"2024-04-27\", desktop: 383, mobile: 420 },\n { date: \"2024-04-28\", desktop: 122, mobile: 180 },\n { date: \"2024-04-29\", desktop: 315, mobile: 240 },\n { date: \"2024-04-30\", desktop: 454, mobile: 380 },\n]\n\nconst chartConfig = {\n views: {\n label: \"Page Views\",\n },\n desktop: {\n label: \"Desktop\",\n color: \"var(--chart-2)\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"var(--chart-1)\",\n },\n} satisfies ChartConfig\n\nexport function ChartDemo() {\n const [activeChart, setActiveChart] =\n React.useState(\"desktop\")\n\n const total = React.useMemo(\n () => ({\n desktop: chartData.reduce((acc, curr) => acc + curr.desktop, 0),\n mobile: chartData.reduce((acc, curr) => acc + curr.mobile, 0),\n }),\n []\n )\n\n return (\n \n \n
\n Bar Chart - Interactive\n \n Showing total visitors for the last 3 months\n \n
\n
\n {[\"desktop\", \"mobile\"].map((key) => {\n const chart = key as keyof typeof chartConfig\n return (\n setActiveChart(chart)}\n >\n \n {chartConfig[chart].label}\n \n \n {total[key as keyof typeof total].toLocaleString()}\n \n \n )\n })}\n
\n
\n \n \n \n \n {\n const date = new Date(value)\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n />\n {\n return new Date(value).toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n })\n }}\n />\n }\n />\n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-example-axis.tsx", + "content": "\"use client\"\n\nimport { Bar, BarChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport { ChartContainer, type ChartConfig } from \"@/components/ui/chart\"\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"#2563eb\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"#60a5fa\",\n },\n} satisfies ChartConfig\n\nexport function ChartBarDemoAxis() {\n return (\n \n \n \n value.slice(0, 3)}\n />\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-example-grid.tsx", + "content": "\"use client\"\n\nimport { Bar, BarChart, CartesianGrid } from \"recharts\"\n\nimport { ChartContainer, type ChartConfig } from \"@/components/ui/chart\"\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"#2563eb\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"#60a5fa\",\n },\n} satisfies ChartConfig\n\nexport function ChartBarDemoGrid() {\n return (\n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-example-legend.tsx", + "content": "\"use client\"\n\nimport { Bar, BarChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n type ChartConfig,\n} from \"@/components/ui/chart\"\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"#2563eb\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"#60a5fa\",\n },\n} satisfies ChartConfig\n\nexport function ChartBarDemoLegend() {\n return (\n \n \n \n value.slice(0, 3)}\n />\n } />\n } />\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-example-tooltip.tsx", + "content": "\"use client\"\n\nimport { Bar, BarChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n type ChartConfig,\n} from \"@/components/ui/chart\"\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"#2563eb\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"#60a5fa\",\n },\n} satisfies ChartConfig\n\nexport function ChartBarDemoTooltip() {\n return (\n \n \n \n value.slice(0, 3)}\n />\n } />\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-example.tsx", + "content": "\"use client\"\n\nimport { Bar, BarChart } from \"recharts\"\n\nimport { ChartContainer, type ChartConfig } from \"@/components/ui/chart\"\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"#2563eb\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"#60a5fa\",\n },\n} satisfies ChartConfig\n\nexport function ChartExample() {\n return (\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-rtl.tsx", + "content": "\"use client\"\n\nimport { Bar, BarChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n type ChartConfig,\n} from \"@/components/ui/chart\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n january: \"January\",\n february: \"February\",\n march: \"March\",\n april: \"April\",\n may: \"May\",\n june: \"June\",\n desktop: \"Desktop\",\n mobile: \"Mobile\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n january: \"يناير\",\n february: \"فبراير\",\n march: \"مارس\",\n april: \"أبريل\",\n may: \"مايو\",\n june: \"يونيو\",\n desktop: \"سطح المكتب\",\n mobile: \"الجوال\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n january: \"ינואר\",\n february: \"פברואר\",\n march: \"מרץ\",\n april: \"אפריל\",\n may: \"מאי\",\n june: \"יוני\",\n desktop: \"מחשב\",\n mobile: \"נייד\",\n },\n },\n}\n\nconst chartData = [\n { month: \"january\", desktop: 186, mobile: 80 },\n { month: \"february\", desktop: 305, mobile: 200 },\n { month: \"march\", desktop: 237, mobile: 120 },\n { month: \"april\", desktop: 73, mobile: 190 },\n { month: \"may\", desktop: 209, mobile: 130 },\n { month: \"june\", desktop: 214, mobile: 140 },\n]\n\nexport function ChartRtl() {\n const { t, dir } = useTranslation(translations, \"ar\")\n\n const chartConfig = {\n desktop: {\n label: t.desktop,\n color: \"var(--chart-2)\",\n },\n mobile: {\n label: t.mobile,\n color: \"var(--chart-1)\",\n },\n } satisfies ChartConfig\n\n return (\n \n \n \n \n (t[value as keyof typeof t] as string).slice(0, 3)\n }\n reversed={dir === \"rtl\"}\n />\n t[value as keyof typeof t] as string}\n />\n }\n labelClassName=\"w-32\"\n />\n } />\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-tooltip.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nexport function ChartTooltipDemo() {\n return (\n
div]:relative [&>div]:flex [&>div]:h-[137px] [&>div]:w-[224px] [&>div]:items-center [&>div]:justify-center [&>div]:p-4\">\n
\n
\n Label\n
\n \n \n \n \n \n \n \n \n \n \n \n
\n
\n
\n Name\n
\n \n \n \n \n \n \n \n \n \n \n \n
\n
\n \n
\n
\n
\n Indicator\n
\n \n \n \n \n \n \n \n \n \n \n \n
\n
\n )\n}\n\nfunction TooltipDemo({\n indicator = \"dot\",\n label,\n payload,\n hideLabel,\n hideIndicator,\n className,\n}: {\n label: string\n hideLabel?: boolean\n hideIndicator?: boolean\n indicator?: \"line\" | \"dot\" | \"dashed\"\n payload: {\n name: string\n value: number\n fill: string\n }[]\n nameKey?: string\n labelKey?: string\n} & React.ComponentProps<\"div\">) {\n const tooltipLabel = hideLabel ? null : (\n
{label}
\n )\n\n if (!payload?.length) {\n return null\n }\n\n const nestLabel = payload.length === 1 && indicator !== \"dot\"\n\n return (\n \n {!nestLabel ? tooltipLabel : null}\n
\n {payload.map((item, index) => {\n const indicatorColor = item.fill\n\n return (\n svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground\",\n indicator === \"dot\" && \"items-center\"\n )}\n >\n <>\n {!hideIndicator && (\n \n )}\n \n
\n {nestLabel ? tooltipLabel : null}\n {item.name}\n
\n \n {item.value.toLocaleString()}\n \n
\n \n
\n )\n })}\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/chart/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/chart.json b/public/r/react/styles/base-luma/chart.json new file mode 100644 index 000000000..c6f450fe2 --- /dev/null +++ b/public/r/react/styles/base-luma/chart.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "chart", + "title": "Chart", + "description": "Charts built with Recharts, themed with the chart color tokens.", + "dependencies": [ + "cn", + "recharts@3.8.0" + ], + "files": [ + { + "path": "src/components/ui/chart.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\nimport * as RechartsPrimitive from \"recharts\"\nimport type { TooltipValueType } from \"recharts\"\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const\n\nconst INITIAL_DIMENSION = { width: 320, height: 200 } as const\ntype TooltipNameType = number | string\n\nexport type ChartConfig = Record<\n string,\n {\n label?: React.ReactNode\n icon?: React.ComponentType\n } & (\n | { color?: string; theme?: never }\n | { color?: never; theme: Record }\n )\n>\n\ntype ChartContextProps = {\n config: ChartConfig\n}\n\nconst ChartContext = React.createContext(null)\n\nfunction useChart() {\n const context = React.useContext(ChartContext)\n\n if (!context) {\n throw new Error(\"useChart must be used within a \")\n }\n\n return context\n}\n\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n initialDimension = INITIAL_DIMENSION,\n ...props\n}: React.ComponentProps<\"div\"> & {\n config: ChartConfig\n children: React.ComponentProps<\n typeof RechartsPrimitive.ResponsiveContainer\n >[\"children\"]\n initialDimension?: {\n width: number\n height: number\n }\n}) {\n const uniqueId = React.useId()\n const chartId = `chart-${id ?? uniqueId.replace(/:/g, \"\")}`\n\n return (\n \n \n \n \n {children}\n \n \n \n )\n}\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(\n ([, config]) => config.theme ?? config.color\n )\n\n if (!colorConfig.length) {\n return null\n }\n\n return (\n `\n${prefix} [data-chart=${id}] {\n${colorConfig\n .map(([key, itemConfig]) => {\n const color =\n itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ??\n itemConfig.color\n return color ? ` --color-${key}: ${color};` : null\n })\n .join(\"\\n\")}\n}\n`\n )\n .join(\"\\n\"),\n }}\n />\n )\n}\n\nconst ChartTooltip = RechartsPrimitive.Tooltip\n\nfunction ChartTooltipContent({\n active,\n payload,\n className,\n indicator = \"dot\",\n hideLabel = false,\n hideIndicator = false,\n label,\n labelFormatter,\n labelClassName,\n formatter,\n color,\n nameKey,\n labelKey,\n}: React.ComponentProps &\n React.ComponentProps<\"div\"> & {\n hideLabel?: boolean\n hideIndicator?: boolean\n indicator?: \"line\" | \"dot\" | \"dashed\"\n nameKey?: string\n labelKey?: string\n } & Omit<\n RechartsPrimitive.DefaultTooltipContentProps<\n TooltipValueType,\n TooltipNameType\n >,\n \"accessibilityLayer\"\n >) {\n const { config } = useChart()\n\n const tooltipLabel = React.useMemo(() => {\n if (hideLabel || !payload?.length) {\n return null\n }\n\n const [item] = payload\n const key = `${labelKey ?? item?.dataKey ?? item?.name ?? \"value\"}`\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\n const value =\n !labelKey && typeof label === \"string\"\n ? (config[label]?.label ?? label)\n : itemConfig?.label\n\n if (labelFormatter) {\n return (\n
\n {labelFormatter(value, payload)}\n
\n )\n }\n\n if (!value) {\n return null\n }\n\n return
{value}
\n }, [\n label,\n labelFormatter,\n payload,\n hideLabel,\n labelClassName,\n config,\n labelKey,\n ])\n\n if (!active || !payload?.length) {\n return null\n }\n\n const nestLabel = payload.length === 1 && indicator !== \"dot\"\n\n return (\n \n {!nestLabel ? tooltipLabel : null}\n
\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.name ?? item.dataKey ?? \"value\"}`\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\n const indicatorColor = color ?? item.payload?.fill ?? item.color\n\n return (\n svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground\",\n indicator === \"dot\" && \"items-center\"\n )}\n >\n {formatter && item?.value !== undefined && item.name ? (\n formatter(item.value, item.name, item, index, item.payload)\n ) : (\n <>\n {itemConfig?.icon ? (\n \n ) : (\n !hideIndicator && (\n \n )\n )}\n \n
\n {nestLabel ? tooltipLabel : null}\n \n {itemConfig?.label ?? item.name}\n \n
\n {item.value != null && (\n \n {typeof item.value === \"number\"\n ? item.value.toLocaleString()\n : String(item.value)}\n \n )}\n
\n \n )}\n \n )\n })}\n \n \n )\n}\n\nconst ChartLegend = RechartsPrimitive.Legend\n\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n payload,\n verticalAlign = \"bottom\",\n nameKey,\n}: React.ComponentProps<\"div\"> & {\n hideIcon?: boolean\n nameKey?: string\n} & RechartsPrimitive.DefaultLegendContentProps) {\n const { config } = useChart()\n\n if (!payload?.length) {\n return null\n }\n\n return (\n \n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.dataKey ?? \"value\"}`\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\n\n return (\n svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground\"\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n \n ) : (\n \n )}\n {itemConfig?.label}\n \n )\n })}\n \n )\n}\n\nfunction getPayloadConfigFromPayload(\n config: ChartConfig,\n payload: unknown,\n key: string\n) {\n if (typeof payload !== \"object\" || payload === null) {\n return undefined\n }\n\n const payloadPayload =\n \"payload\" in payload &&\n typeof payload.payload === \"object\" &&\n payload.payload !== null\n ? payload.payload\n : undefined\n\n let configLabelKey: string = key\n\n if (\n key in payload &&\n typeof payload[key as keyof typeof payload] === \"string\"\n ) {\n configLabelKey = payload[key as keyof typeof payload] as string\n } else if (\n payloadPayload &&\n key in payloadPayload &&\n typeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\n ) {\n configLabelKey = payloadPayload[\n key as keyof typeof payloadPayload\n ] as string\n }\n\n return configLabelKey in config ? config[configLabelKey] : config[key]\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/chart/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/checkbox-examples.json b/public/r/react/styles/base-luma/checkbox-examples.json new file mode 100644 index 000000000..e28ca58d5 --- /dev/null +++ b/public/r/react/styles/base-luma/checkbox-examples.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "checkbox-examples", + "title": "Checkbox examples", + "description": "The examples from the shadcn/ui Checkbox docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/checkbox", + "@fulldev/field", + "@fulldev/label", + "@fulldev/select", + "@fulldev/table" + ], + "files": [ + { + "path": "src/components/examples/checkbox/checkbox-basic.tsx", + "content": "import { Checkbox } from \"@/components/ui/checkbox\"\nimport { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\"\n\nexport function CheckboxBasic() {\n return (\n \n \n \n \n Accept terms and conditions\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-demo.tsx", + "content": "\"use client\"\n\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldTitle,\n} from \"@/components/ui/field\"\nimport { Label } from \"@/components/ui/label\"\n\nexport function CheckboxDemo() {\n return (\n \n \n \n \n \n \n \n \n \n Accept terms and conditions\n \n \n By clicking this checkbox, you agree to the terms.\n \n \n \n \n \n Enable notifications\n \n \n \n \n \n Enable notifications\n \n You can enable or disable notifications at any time.\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-description.tsx", + "content": "import { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n} from \"@/components/ui/field\"\n\nexport function CheckboxDescription() {\n return (\n \n \n \n \n \n Accept terms and conditions\n \n \n By clicking this checkbox, you agree to the terms and conditions.\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-disabled.tsx", + "content": "import { Checkbox } from \"@/components/ui/checkbox\"\nimport { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\"\n\nexport function CheckboxDisabled() {\n return (\n \n \n \n \n Enable notifications\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-group.tsx", + "content": "import { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSet,\n} from \"@/components/ui/field\"\n\nexport function CheckboxGroup() {\n return (\n
\n \n Show these items on the desktop:\n \n \n Select the items you want to show on the desktop.\n \n \n \n \n \n Hard disks\n \n \n \n \n \n External disks\n \n \n \n \n \n CDs, DVDs, and iPods\n \n \n \n \n \n Connected servers\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-invalid.tsx", + "content": "import { Checkbox } from \"@/components/ui/checkbox\"\nimport { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\"\n\nexport function CheckboxInvalid() {\n return (\n \n \n \n \n Accept terms and conditions\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldTitle,\n} from \"@/components/ui/field\"\nimport { Label } from \"@/components/ui/label\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n acceptTerms: \"Accept terms and conditions\",\n acceptTermsDescription:\n \"By clicking this checkbox, you agree to the terms.\",\n enableNotifications: \"Enable notifications\",\n enableNotificationsDescription:\n \"You can enable or disable notifications at any time.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n acceptTerms: \"قبول الشروط والأحكام\",\n acceptTermsDescription: \"بالنقر على هذا المربع، فإنك توافق على الشروط.\",\n enableNotifications: \"تفعيل الإشعارات\",\n enableNotificationsDescription:\n \"يمكنك تفعيل أو إلغاء تفعيل الإشعارات في أي وقت.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n acceptTerms: \"קבל תנאים והגבלות\",\n acceptTermsDescription:\n \"על ידי לחיצה על תיבת הסימון הזו, אתה מסכים לתנאים.\",\n enableNotifications: \"הפעל התראות\",\n enableNotificationsDescription:\n \"אתה יכול להפעיל או להשבית התראות בכל עת.\",\n },\n },\n}\n\nexport function CheckboxRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n \n \n \n \n \n \n \n \n \n {t.acceptTerms}\n \n {t.acceptTermsDescription}\n \n \n \n \n \n {t.enableNotifications}\n \n \n \n \n \n \n {t.enableNotifications}\n \n {t.enableNotificationsDescription}\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-table.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"@/components/ui/table\"\n\nconst tableData = [\n {\n id: \"1\",\n name: \"Sarah Chen\",\n email: \"sarah.chen@example.com\",\n role: \"Admin\",\n },\n {\n id: \"2\",\n name: \"Marcus Rodriguez\",\n email: \"marcus.rodriguez@example.com\",\n role: \"User\",\n },\n {\n id: \"3\",\n name: \"Priya Patel\",\n email: \"priya.patel@example.com\",\n role: \"User\",\n },\n {\n id: \"4\",\n name: \"David Kim\",\n email: \"david.kim@example.com\",\n role: \"Editor\",\n },\n]\n\nexport function CheckboxInTable() {\n const [selectedRows, setSelectedRows] = React.useState>(\n new Set([\"1\"])\n )\n\n const selectAll = selectedRows.size === tableData.length\n\n const handleSelectAll = (checked: boolean) => {\n if (checked) {\n setSelectedRows(new Set(tableData.map((row) => row.id)))\n } else {\n setSelectedRows(new Set())\n }\n }\n\n const handleSelectRow = (id: string, checked: boolean) => {\n const newSelected = new Set(selectedRows)\n if (checked) {\n newSelected.add(id)\n } else {\n newSelected.delete(id)\n }\n setSelectedRows(newSelected)\n }\n\n return (\n \n \n \n \n \n \n Name\n Email\n Role\n \n \n \n {tableData.map((row) => (\n \n \n \n handleSelectRow(row.id, checked === true)\n }\n />\n \n {row.name}\n {row.email}\n {row.role}\n \n ))}\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/checkbox/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/checkbox.json b/public/r/react/styles/base-luma/checkbox.json new file mode 100644 index 000000000..bc7ad8ec0 --- /dev/null +++ b/public/r/react/styles/base-luma/checkbox.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "checkbox", + "title": "Checkbox", + "description": "A control that allows the user to toggle between checked and not checked.", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/checkbox.tsx", + "content": "\"use client\"\n\nimport { Checkbox as CheckboxPrimitive } from \"@base-ui/react/checkbox\"\nimport { cn } from \"cn\"\nimport { CheckIcon } from \"lucide-react\"\n\nfunction Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {\n return (\n \n svg]:size-3.5 grid place-content-center text-current transition-none\"\n >\n \n \n \n )\n}\n\nexport { Checkbox }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/checkbox/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/collapsible-examples.json b/public/r/react/styles/base-luma/collapsible-examples.json new file mode 100644 index 000000000..a0bbcf87c --- /dev/null +++ b/public/r/react/styles/base-luma/collapsible-examples.json @@ -0,0 +1,53 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "collapsible-examples", + "title": "Collapsible examples", + "description": "The examples from the shadcn/ui Collapsible docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/collapsible", + "@fulldev/field", + "@fulldev/input", + "@fulldev/select", + "@fulldev/tabs" + ], + "files": [ + { + "path": "src/components/examples/collapsible/collapsible-basic.tsx", + "content": "import { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\n\nexport function CollapsibleBasic() {\n return (\n \n \n \n }\n >\n Product details\n \n \n \n
\n This panel can be expanded or collapsed to reveal additional\n content.\n
\n \n
\n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/collapsible/collapsible-demo.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronsUpDown } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\n\nexport function CollapsibleDemo() {\n const [isOpen, setIsOpen] = React.useState(false)\n\n return (\n \n
\n

Order #4189

\n }\n >\n \n Toggle details\n \n
\n
\n Status\n Shipped\n
\n \n
\n

Shipping address

\n

100 Market St, San Francisco

\n
\n
\n

Items

\n

2x Studio Headphones

\n
\n
\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/collapsible/collapsible-file-tree.tsx", + "content": "import { ChevronRightIcon, FileIcon, FolderIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Card, CardContent, CardHeader } from \"@/components/ui/card\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport { Tabs, TabsList, TabsTrigger } from \"@/components/ui/tabs\"\n\ntype FileTreeItem = { name: string } | { name: string; items: FileTreeItem[] }\n\nexport function CollapsibleFileTree() {\n const fileTree: FileTreeItem[] = [\n {\n name: \"components\",\n items: [\n {\n name: \"ui\",\n items: [\n { name: \"button.tsx\" },\n { name: \"card.tsx\" },\n { name: \"dialog.tsx\" },\n { name: \"input.tsx\" },\n { name: \"select.tsx\" },\n { name: \"table.tsx\" },\n ],\n },\n { name: \"login-form.tsx\" },\n { name: \"register-form.tsx\" },\n ],\n },\n {\n name: \"lib\",\n items: [{ name: \"utils.ts\" }, { name: \"cn.ts\" }, { name: \"api.ts\" }],\n },\n {\n name: \"hooks\",\n items: [\n { name: \"use-media-query.ts\" },\n { name: \"use-debounce.ts\" },\n { name: \"use-local-storage.ts\" },\n ],\n },\n {\n name: \"types\",\n items: [{ name: \"index.d.ts\" }, { name: \"api.d.ts\" }],\n },\n {\n name: \"public\",\n items: [\n { name: \"favicon.ico\" },\n { name: \"logo.svg\" },\n { name: \"images\" },\n ],\n },\n { name: \"app.tsx\" },\n { name: \"layout.tsx\" },\n { name: \"globals.css\" },\n { name: \"package.json\" },\n { name: \"tsconfig.json\" },\n { name: \"README.md\" },\n { name: \".gitignore\" },\n ]\n\n const renderItem = (fileItem: FileTreeItem) => {\n if (\"items\" in fileItem) {\n return (\n \n \n }\n >\n \n \n {fileItem.name}\n \n \n
\n {fileItem.items.map((child) => renderItem(child))}\n
\n
\n
\n )\n }\n return (\n \n \n {fileItem.name}\n \n )\n }\n\n return (\n \n \n \n \n Explorer\n Outline\n \n \n \n \n
\n {fileTree.map((item) => renderItem(item))}\n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/collapsible/collapsible-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronsUpDown } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n orderNumber: \"Order #4189\",\n status: \"Status\",\n shipped: \"Shipped\",\n shippingAddress: \"Shipping address\",\n address: \"100 Market St, San Francisco\",\n items: \"Items\",\n itemsDescription: \"2x Studio Headphones\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n orderNumber: \"الطلب #4189\",\n status: \"الحالة\",\n shipped: \"تم الشحن\",\n shippingAddress: \"عنوان الشحن\",\n address: \"100 Market St, San Francisco\",\n items: \"العناصر\",\n itemsDescription: \"2x سماعات الاستوديو\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n orderNumber: \"הזמנה #4189\",\n status: \"סטטוס\",\n shipped: \"נשלח\",\n shippingAddress: \"כתובת משלוח\",\n address: \"100 Market St, San Francisco\",\n items: \"פריטים\",\n itemsDescription: \"2x אוזניות סטודיו\",\n },\n },\n}\n\nexport function CollapsibleRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n const [isOpen, setIsOpen] = React.useState(false)\n\n return (\n \n
\n

{t.orderNumber}

\n }\n >\n \n Toggle details\n \n
\n
\n {t.status}\n {t.shipped}\n
\n \n
\n

{t.shippingAddress}

\n

{t.address}

\n
\n
\n

{t.items}

\n

{t.itemsDescription}

\n
\n
\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/collapsible/collapsible-settings.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { MaximizeIcon, MinimizeIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function CollapsibleSettings() {\n const [isOpen, setIsOpen] = React.useState(false)\n\n return (\n \n \n Radius\n Set the corner radius of the element.\n \n \n \n \n \n \n Radius X\n \n \n \n \n \n Radius Y\n \n \n \n \n \n \n Radius X\n \n \n \n \n \n Radius Y\n \n \n \n \n \n }>\n {isOpen ? : }\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/collapsible/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/collapsible.json b/public/r/react/styles/base-luma/collapsible.json new file mode 100644 index 000000000..ae76fbb7c --- /dev/null +++ b/public/r/react/styles/base-luma/collapsible.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "collapsible", + "title": "Collapsible", + "description": "An interactive component which expands/collapses a panel.", + "dependencies": [ + "@base-ui/react" + ], + "files": [ + { + "path": "src/components/ui/collapsible.tsx", + "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"@base-ui/react/collapsible\"\n\nfunction Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {\n return \n}\n\nfunction CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {\n return (\n \n )\n}\n\nfunction CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) {\n return (\n \n )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/collapsible/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/combobox-examples.json b/public/r/react/styles/base-luma/combobox-examples.json new file mode 100644 index 000000000..eae2f6bd4 --- /dev/null +++ b/public/r/react/styles/base-luma/combobox-examples.json @@ -0,0 +1,87 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "combobox-examples", + "title": "Combobox examples", + "description": "The examples from the shadcn/ui Combobox docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/combobox", + "@fulldev/field", + "@fulldev/input-group", + "@fulldev/item", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/combobox/combobox-auto-highlight.tsx", + "content": "\"use client\"\n\nimport {\n Combobox,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n} from \"@/components/ui/combobox\"\n\nconst frameworks = [\n \"Next.js\",\n \"SvelteKit\",\n \"Nuxt.js\",\n \"Remix\",\n \"Astro\",\n] as const\n\nexport function ComboboxAutoHighlight() {\n return (\n \n \n \n No items found.\n \n {(item) => (\n \n {item}\n \n )}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-basic.tsx", + "content": "\"use client\"\n\nimport {\n Combobox,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n} from \"@/components/ui/combobox\"\n\nconst frameworks = [\n \"Next.js\",\n \"SvelteKit\",\n \"Nuxt.js\",\n \"Remix\",\n \"Astro\",\n] as const\n\nexport function ComboboxBasic() {\n return (\n \n \n \n No items found.\n \n {(item) => (\n \n {item}\n \n )}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-clear.tsx", + "content": "\"use client\"\n\nimport {\n Combobox,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n} from \"@/components/ui/combobox\"\n\nconst frameworks = [\n \"Next.js\",\n \"SvelteKit\",\n \"Nuxt.js\",\n \"Remix\",\n \"Astro\",\n] as const\n\nexport function ComboboxWithClear() {\n return (\n \n \n \n No items found.\n \n {(item) => (\n \n {item}\n \n )}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-custom.tsx", + "content": "\"use client\"\n\nimport {\n Combobox,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n} from \"@/components/ui/combobox\"\nimport {\n Item,\n ItemContent,\n ItemDescription,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nconst countries = [\n { code: \"\", value: \"\", continent: \"\", label: \"Select country\" },\n {\n code: \"ar\",\n value: \"argentina\",\n label: \"Argentina\",\n continent: \"South America\",\n },\n { code: \"au\", value: \"australia\", label: \"Australia\", continent: \"Oceania\" },\n { code: \"br\", value: \"brazil\", label: \"Brazil\", continent: \"South America\" },\n { code: \"ca\", value: \"canada\", label: \"Canada\", continent: \"North America\" },\n { code: \"cn\", value: \"china\", label: \"China\", continent: \"Asia\" },\n {\n code: \"co\",\n value: \"colombia\",\n label: \"Colombia\",\n continent: \"South America\",\n },\n { code: \"eg\", value: \"egypt\", label: \"Egypt\", continent: \"Africa\" },\n { code: \"fr\", value: \"france\", label: \"France\", continent: \"Europe\" },\n { code: \"de\", value: \"germany\", label: \"Germany\", continent: \"Europe\" },\n { code: \"it\", value: \"italy\", label: \"Italy\", continent: \"Europe\" },\n { code: \"jp\", value: \"japan\", label: \"Japan\", continent: \"Asia\" },\n { code: \"ke\", value: \"kenya\", label: \"Kenya\", continent: \"Africa\" },\n { code: \"mx\", value: \"mexico\", label: \"Mexico\", continent: \"North America\" },\n {\n code: \"nz\",\n value: \"new-zealand\",\n label: \"New Zealand\",\n continent: \"Oceania\",\n },\n { code: \"ng\", value: \"nigeria\", label: \"Nigeria\", continent: \"Africa\" },\n {\n code: \"za\",\n value: \"south-africa\",\n label: \"South Africa\",\n continent: \"Africa\",\n },\n { code: \"kr\", value: \"south-korea\", label: \"South Korea\", continent: \"Asia\" },\n {\n code: \"gb\",\n value: \"united-kingdom\",\n label: \"United Kingdom\",\n continent: \"Europe\",\n },\n {\n code: \"us\",\n value: \"united-states\",\n label: \"United States\",\n continent: \"North America\",\n },\n]\n\nexport function ComboboxWithCustomItems() {\n return (\n country.code !== \"\")}\n itemToStringValue={(country: (typeof countries)[number]) => country.label}\n >\n \n \n No countries found.\n \n {(country) => (\n \n \n \n \n {country.label}\n \n \n {country.continent} ({country.code})\n \n \n \n \n )}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-demo.tsx", + "content": "\"use client\"\n\nimport {\n Combobox,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n} from \"@/components/ui/combobox\"\n\nconst frameworks = [\n \"Next.js\",\n \"SvelteKit\",\n \"Nuxt.js\",\n \"Remix\",\n \"Astro\",\n] as const\n\nexport function ComboboxBasic() {\n return (\n \n \n \n No items found.\n \n {(item) => (\n \n {item}\n \n )}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-disabled.tsx", + "content": "\"use client\"\n\nimport {\n Combobox,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n} from \"@/components/ui/combobox\"\n\nconst frameworks = [\n \"Next.js\",\n \"SvelteKit\",\n \"Nuxt.js\",\n \"Remix\",\n \"Astro\",\n] as const\n\nexport function ComboboxDisabled() {\n return (\n \n \n \n No items found.\n \n {(item) => (\n \n {item}\n \n )}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-groups.tsx", + "content": "\"use client\"\n\nimport {\n Combobox,\n ComboboxCollection,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxGroup,\n ComboboxInput,\n ComboboxItem,\n ComboboxLabel,\n ComboboxList,\n ComboboxSeparator,\n} from \"@/components/ui/combobox\"\n\nconst timezones = [\n {\n value: \"Americas\",\n items: [\n \"(GMT-5) New York\",\n \"(GMT-8) Los Angeles\",\n \"(GMT-6) Chicago\",\n \"(GMT-5) Toronto\",\n \"(GMT-8) Vancouver\",\n \"(GMT-3) São Paulo\",\n ],\n },\n {\n value: \"Europe\",\n items: [\n \"(GMT+0) London\",\n \"(GMT+1) Paris\",\n \"(GMT+1) Berlin\",\n \"(GMT+1) Rome\",\n \"(GMT+1) Madrid\",\n \"(GMT+1) Amsterdam\",\n ],\n },\n {\n value: \"Asia/Pacific\",\n items: [\n \"(GMT+9) Tokyo\",\n \"(GMT+8) Shanghai\",\n \"(GMT+8) Singapore\",\n \"(GMT+4) Dubai\",\n \"(GMT+11) Sydney\",\n \"(GMT+9) Seoul\",\n ],\n },\n] as const\n\nexport function ComboboxWithGroupsAndSeparator() {\n return (\n \n \n \n No timezones found.\n \n {(group, index) => (\n \n {group.value}\n \n {(item) => (\n \n {item}\n \n )}\n \n {index < timezones.length - 1 && }\n \n )}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-input-group.tsx", + "content": "\"use client\"\n\nimport { GlobeIcon } from \"lucide-react\"\n\nimport {\n Combobox,\n ComboboxCollection,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxGroup,\n ComboboxInput,\n ComboboxItem,\n ComboboxLabel,\n ComboboxList,\n} from \"@/components/ui/combobox\"\nimport { InputGroupAddon } from \"@/components/ui/input-group\"\n\nconst timezones = [\n {\n value: \"Americas\",\n items: [\n \"(GMT-5) New York\",\n \"(GMT-8) Los Angeles\",\n \"(GMT-6) Chicago\",\n \"(GMT-5) Toronto\",\n \"(GMT-8) Vancouver\",\n \"(GMT-3) São Paulo\",\n ],\n },\n {\n value: \"Europe\",\n items: [\n \"(GMT+0) London\",\n \"(GMT+1) Paris\",\n \"(GMT+1) Berlin\",\n \"(GMT+1) Rome\",\n \"(GMT+1) Madrid\",\n \"(GMT+1) Amsterdam\",\n ],\n },\n {\n value: \"Asia/Pacific\",\n items: [\n \"(GMT+9) Tokyo\",\n \"(GMT+8) Shanghai\",\n \"(GMT+8) Singapore\",\n \"(GMT+4) Dubai\",\n \"(GMT+11) Sydney\",\n \"(GMT+9) Seoul\",\n ],\n },\n] as const\n\nexport function ComboxboxInputGroup() {\n return (\n \n \n \n \n \n \n \n No timezones found.\n \n {(group) => (\n \n {group.value}\n \n {(item) => (\n \n {item}\n \n )}\n \n \n )}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-invalid.tsx", + "content": "\"use client\"\n\nimport {\n Combobox,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n} from \"@/components/ui/combobox\"\n\nconst frameworks = [\n \"Next.js\",\n \"SvelteKit\",\n \"Nuxt.js\",\n \"Remix\",\n \"Astro\",\n] as const\n\nexport function ComboboxInvalid() {\n return (\n \n \n \n No items found.\n \n {(item) => (\n \n {item}\n \n )}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-multiple.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Combobox,\n ComboboxChip,\n ComboboxChips,\n ComboboxChipsInput,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxItem,\n ComboboxList,\n ComboboxValue,\n useComboboxAnchor,\n} from \"@/components/ui/combobox\"\n\nconst frameworks = [\n \"Next.js\",\n \"SvelteKit\",\n \"Nuxt.js\",\n \"Remix\",\n \"Astro\",\n] as const\n\nexport function ComboboxMultiple() {\n const anchor = useComboboxAnchor()\n\n return (\n \n \n \n {(values) => (\n \n {values.map((value: string) => (\n {value}\n ))}\n \n \n )}\n \n \n \n No items found.\n \n {(item) => (\n \n {item}\n \n )}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-popup.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Combobox,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n ComboboxTrigger,\n ComboboxValue,\n} from \"@/components/ui/combobox\"\n\nconst countries = [\n { code: \"\", value: \"\", continent: \"\", label: \"Select country\" },\n {\n code: \"ar\",\n value: \"argentina\",\n label: \"Argentina\",\n continent: \"South America\",\n },\n { code: \"au\", value: \"australia\", label: \"Australia\", continent: \"Oceania\" },\n { code: \"br\", value: \"brazil\", label: \"Brazil\", continent: \"South America\" },\n { code: \"ca\", value: \"canada\", label: \"Canada\", continent: \"North America\" },\n { code: \"cn\", value: \"china\", label: \"China\", continent: \"Asia\" },\n {\n code: \"co\",\n value: \"colombia\",\n label: \"Colombia\",\n continent: \"South America\",\n },\n { code: \"eg\", value: \"egypt\", label: \"Egypt\", continent: \"Africa\" },\n { code: \"fr\", value: \"france\", label: \"France\", continent: \"Europe\" },\n { code: \"de\", value: \"germany\", label: \"Germany\", continent: \"Europe\" },\n { code: \"it\", value: \"italy\", label: \"Italy\", continent: \"Europe\" },\n { code: \"jp\", value: \"japan\", label: \"Japan\", continent: \"Asia\" },\n { code: \"ke\", value: \"kenya\", label: \"Kenya\", continent: \"Africa\" },\n { code: \"mx\", value: \"mexico\", label: \"Mexico\", continent: \"North America\" },\n {\n code: \"nz\",\n value: \"new-zealand\",\n label: \"New Zealand\",\n continent: \"Oceania\",\n },\n { code: \"ng\", value: \"nigeria\", label: \"Nigeria\", continent: \"Africa\" },\n {\n code: \"za\",\n value: \"south-africa\",\n label: \"South Africa\",\n continent: \"Africa\",\n },\n { code: \"kr\", value: \"south-korea\", label: \"South Korea\", continent: \"Asia\" },\n {\n code: \"gb\",\n value: \"united-kingdom\",\n label: \"United Kingdom\",\n continent: \"Europe\",\n },\n {\n code: \"us\",\n value: \"united-states\",\n label: \"United States\",\n continent: \"North America\",\n },\n]\n\nexport function ComboboxPopup() {\n return (\n <>\n \n \n }\n >\n \n \n \n \n No items found.\n \n {(item) => (\n \n {item.label}\n \n )}\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Combobox,\n ComboboxChip,\n ComboboxChips,\n ComboboxChipsInput,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxItem,\n ComboboxList,\n ComboboxValue,\n useComboboxAnchor,\n} from \"@/components/ui/combobox\"\nimport { Field, FieldLabel } from \"@/components/ui/field\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst categories = [\n \"technology\",\n \"design\",\n \"business\",\n \"marketing\",\n \"education\",\n \"health\",\n] as const\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n label: \"Categories\",\n placeholder: \"Add categories\",\n empty: \"No categories found.\",\n technology: \"Technology\",\n design: \"Design\",\n business: \"Business\",\n marketing: \"Marketing\",\n education: \"Education\",\n health: \"Health\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n label: \"الفئات\",\n placeholder: \"أضف فئات\",\n empty: \"لم يتم العثور على فئات.\",\n technology: \"التكنولوجيا\",\n design: \"التصميم\",\n business: \"الأعمال\",\n marketing: \"التسويق\",\n education: \"التعليم\",\n health: \"الصحة\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n label: \"קטגוריות\",\n placeholder: \"הוסף קטגוריות\",\n empty: \"לא נמצאו קטגוריות.\",\n technology: \"טכנולוגיה\",\n design: \"עיצוב\",\n business: \"עסקים\",\n marketing: \"שיווק\",\n education: \"חינוך\",\n health: \"בריאות\",\n },\n },\n}\n\nexport function ComboboxRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n const anchor = useComboboxAnchor()\n\n const categoryLabels: Record = {\n technology: t.technology,\n design: t.design,\n business: t.business,\n marketing: t.marketing,\n education: t.education,\n health: t.health,\n }\n\n return (\n \n {t.label}\n \n categoryLabels[item] || item\n }\n >\n \n \n {(values) => (\n \n {values.map((value: string) => (\n \n {categoryLabels[value] || value}\n \n ))}\n \n \n )}\n \n \n \n {t.empty}\n \n {(item) => (\n \n {categoryLabels[item] || item}\n \n )}\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/combobox/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/combobox.json b/public/r/react/styles/base-luma/combobox.json new file mode 100644 index 000000000..d7976155c --- /dev/null +++ b/public/r/react/styles/base-luma/combobox.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "combobox", + "title": "Combobox", + "description": "Autocomplete input with a list of suggestions.", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/input-group" + ], + "files": [ + { + "path": "src/components/ui/combobox.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Combobox as ComboboxPrimitive } from \"@base-ui/react\"\nimport { cn } from \"cn\"\nimport { CheckIcon, ChevronDownIcon, XIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n\nconst Combobox = ComboboxPrimitive.Root\n\nfunction ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {\n return \n}\n\nfunction ComboboxTrigger({\n className,\n children,\n ...props\n}: ComboboxPrimitive.Trigger.Props) {\n return (\n \n {children}\n \n \n )\n}\n\nfunction ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {\n return (\n }\n className={cn(className)}\n {...props}\n >\n \n \n )\n}\n\nfunction ComboboxInput({\n className,\n children,\n disabled = false,\n showTrigger = true,\n showClear = false,\n ...props\n}: ComboboxPrimitive.Input.Props & {\n showTrigger?: boolean\n showClear?: boolean\n}) {\n return (\n \n }\n {...props}\n />\n \n {showTrigger && (\n }\n data-slot=\"input-group-button\"\n className=\"group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent\"\n disabled={disabled}\n />\n )}\n {showClear && }\n \n {children}\n \n )\n}\n\nfunction ComboboxContent({\n className,\n side = \"bottom\",\n sideOffset = 6,\n align = \"start\",\n alignOffset = 0,\n anchor,\n ...props\n}: ComboboxPrimitive.Popup.Props &\n Pick<\n ComboboxPrimitive.Positioner.Props,\n \"side\" | \"align\" | \"sideOffset\" | \"alignOffset\" | \"anchor\"\n >) {\n return (\n \n \n \n \n \n )\n}\n\nfunction ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {\n return (\n \n )\n}\n\nfunction ComboboxItem({\n className,\n children,\n ...props\n}: ComboboxPrimitive.Item.Props) {\n return (\n \n {children}\n }\n >\n \n \n \n )\n}\n\nfunction ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) {\n return (\n \n )\n}\n\nfunction ComboboxLabel({\n className,\n ...props\n}: ComboboxPrimitive.GroupLabel.Props) {\n return (\n \n )\n}\n\nfunction ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) {\n return (\n \n )\n}\n\nfunction ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {\n return (\n
\n
\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-natural-language.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { parseDate } from \"chrono-node\"\nimport { CalendarIcon } from \"lucide-react\"\n\nimport { Calendar } from \"@/components/ui/calendar\"\nimport { Field, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n\nfunction formatDate(date: Date | undefined) {\n if (!date) {\n return \"\"\n }\n\n return date.toLocaleDateString(\"en-US\", {\n day: \"2-digit\",\n month: \"long\",\n year: \"numeric\",\n })\n}\n\nexport function DatePickerNaturalLanguage() {\n const [open, setOpen] = React.useState(false)\n const [value, setValue] = React.useState(\"In 2 days\")\n const [date, setDate] = React.useState(\n parseDate(value) || undefined\n )\n\n return (\n \n Schedule Date\n \n {\n setValue(e.target.value)\n const date = parseDate(e.target.value)\n if (date) {\n setDate(date)\n }\n }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault()\n setOpen(true)\n }\n }}\n />\n \n \n \n }\n >\n \n Select date\n \n \n {\n setDate(date)\n setValue(formatDate(date))\n setOpen(false)\n }}\n />\n \n \n \n \n
\n Your post will be published on{\" \"}\n {formatDate(date)}.\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-range.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { addDays, format } from \"date-fns\"\nimport { CalendarIcon } from \"lucide-react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Calendar } from \"@/components/ui/calendar\"\nimport { Field, FieldLabel } from \"@/components/ui/field\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n\nexport function DatePickerWithRange() {\n const [date, setDate] = React.useState({\n from: new Date(new Date().getFullYear(), 0, 20),\n to: addDays(new Date(new Date().getFullYear(), 0, 20), 20),\n })\n\n return (\n \n Date Picker Range\n \n \n }\n >\n \n {date?.from ? (\n date.to ? (\n <>\n {format(date.from, \"LLL dd, y\")} -{\" \"}\n {format(date.to, \"LLL dd, y\")}\n \n ) : (\n format(date.from, \"LLL dd, y\")\n )\n ) : (\n Pick a date\n )}\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { format } from \"date-fns\"\nimport { arSA, he } from \"date-fns/locale\"\nimport { ChevronDownIcon } from \"lucide-react\"\nimport {\n arSA as arSADayPicker,\n he as heDayPicker,\n} from \"react-day-picker/locale\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Calendar } from \"@/components/ui/calendar\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n placeholder: \"Pick a date\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n placeholder: \"اختر تاريخًا\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n placeholder: \"בחר תאריך\",\n },\n },\n}\n\nconst dayPickerLocales = {\n ar: arSADayPicker,\n he: heDayPicker,\n} as const\n\nconst dateFnsLocales = {\n ar: arSA,\n he: he,\n} as const\n\nexport function DatePickerRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n const [date, setDate] = React.useState()\n\n const dateFnsLocale =\n dir === \"rtl\"\n ? dateFnsLocales[language as keyof typeof dateFnsLocales]\n : undefined\n const dayPickerLocale =\n dir === \"rtl\"\n ? dayPickerLocales[language as keyof typeof dayPickerLocales]\n : undefined\n\n return (\n \n \n }\n >\n {date ? (\n format(date, \"PPP\", { locale: dateFnsLocale })\n ) : (\n {t.placeholder}\n )}\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-time.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { format } from \"date-fns\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Calendar } from \"@/components/ui/calendar\"\nimport { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n\nexport function DatePickerTime() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState(undefined)\n\n return (\n \n \n Date\n \n \n }\n >\n {date ? format(date, \"PPP\") : \"Select date\"}\n \n \n \n {\n setDate(date)\n setOpen(false)\n }}\n />\n \n \n \n \n Time\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/date-picker/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/dialog-examples.json b/public/r/react/styles/base-luma/dialog-examples.json new file mode 100644 index 000000000..56d615d5c --- /dev/null +++ b/public/r/react/styles/base-luma/dialog-examples.json @@ -0,0 +1,56 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "dialog-examples", + "title": "Dialog examples", + "description": "The examples from the shadcn/ui Dialog docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/dialog", + "@fulldev/field", + "@fulldev/input", + "@fulldev/label", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/dialog/dialog-close-button.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\"\nimport { Input } from \"@/components/ui/input\"\nimport { Label } from \"@/components/ui/label\"\n\nexport function DialogCloseButton() {\n return (\n \n }>Share\n \n \n Share link\n \n Anyone who has this link will be able to view this.\n \n \n
\n
\n \n \n
\n
\n \n }>Close\n \n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dialog/dialog-demo.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\"\nimport { Field, FieldGroup } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport { Label } from \"@/components/ui/label\"\n\nexport function DialogDemo() {\n return (\n \n
\n }>\n Open Dialog\n \n \n \n Edit profile\n \n Make changes to your profile here. Click save when you're\n done.\n \n \n \n \n \n \n \n \n \n \n \n \n \n }>\n Cancel\n \n \n \n \n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dialog/dialog-no-close-button.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\"\n\nexport function DialogNoCloseButton() {\n return (\n \n }>\n No Close Button\n \n \n \n No Close Button\n \n This dialog doesn't have a close button in the top-right\n corner.\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dialog/dialog-rtl.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\"\nimport { Field, FieldGroup } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport { Label } from \"@/components/ui/label\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n openDialog: \"Open Dialog\",\n editProfile: \"Edit profile\",\n description:\n \"Make changes to your profile here. Click save when you're done.\",\n name: \"Name\",\n username: \"Username\",\n cancel: \"Cancel\",\n saveChanges: \"Save changes\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n openDialog: \"فتح الحوار\",\n editProfile: \"تعديل الملف الشخصي\",\n description:\n \"قم بإجراء تغييرات على ملفك الشخصي هنا. انقر فوق حفظ عند الانتهاء.\",\n name: \"الاسم\",\n username: \"اسم المستخدم\",\n cancel: \"إلغاء\",\n saveChanges: \"حفظ التغييرات\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n openDialog: \"פתח דיאלוג\",\n editProfile: \"ערוך פרופיל\",\n description: \"בצע שינויים בפרופיל שלך כאן. לחץ על שמור כשתסיים.\",\n name: \"שם\",\n username: \"שם משתמש\",\n cancel: \"בטל\",\n saveChanges: \"שמור שינויים\",\n },\n },\n}\n\nexport function DialogRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n\n return (\n \n
\n }>\n {t.openDialog}\n \n \n \n {t.editProfile}\n {t.description}\n \n \n \n \n \n \n \n \n \n \n \n \n }>\n {t.cancel}\n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dialog/dialog-scrollable-content.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\"\n\nexport function DialogScrollableContent() {\n return (\n \n }>\n Scrollable Content\n \n \n \n Scrollable Content\n \n This is a dialog with scrollable content.\n \n \n
\n {Array.from({ length: 10 }).map((_, index) => (\n

\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do\n eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut\n enim ad minim veniam, quis nostrud exercitation ullamco laboris\n nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in\n reprehenderit in voluptate velit esse cillum dolore eu fugiat\n nulla pariatur. Excepteur sint occaecat cupidatat non proident,\n sunt in culpa qui officia deserunt mollit anim id est laborum.\n

\n ))}\n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dialog/dialog-sticky-footer.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\"\n\nexport function DialogStickyFooter() {\n return (\n \n }>\n Sticky Footer\n \n \n \n Sticky Footer\n \n This dialog has a sticky footer that stays visible while the content\n scrolls.\n \n \n
\n {Array.from({ length: 10 }).map((_, index) => (\n

\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do\n eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut\n enim ad minim veniam, quis nostrud exercitation ullamco laboris\n nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in\n reprehenderit in voluptate velit esse cillum dolore eu fugiat\n nulla pariatur. Excepteur sint occaecat cupidatat non proident,\n sunt in culpa qui officia deserunt mollit anim id est laborum.\n

\n ))}\n
\n \n }>Close\n \n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/dialog/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/dialog.json b/public/r/react/styles/base-luma/dialog.json new file mode 100644 index 000000000..821f15272 --- /dev/null +++ b/public/r/react/styles/base-luma/dialog.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "dialog", + "title": "Dialog", + "description": "A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/dialog.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Dialog as DialogPrimitive } from \"@base-ui/react/dialog\"\nimport { cn } from \"cn\"\nimport { XIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nfunction Dialog({ ...props }: DialogPrimitive.Root.Props) {\n return \n}\n\nfunction DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {\n return \n}\n\nfunction DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {\n return \n}\n\nfunction DialogClose({ ...props }: DialogPrimitive.Close.Props) {\n return \n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: DialogPrimitive.Backdrop.Props) {\n return (\n \n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: DialogPrimitive.Popup.Props & {\n showCloseButton?: boolean\n}) {\n return (\n \n \n \n {children}\n {showCloseButton && (\n \n }\n >\n \n Close\n \n )}\n \n \n )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction DialogFooter({\n className,\n showCloseButton = false,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showCloseButton?: boolean\n}) {\n return (\n \n {children}\n {showCloseButton && (\n }>\n Close\n \n )}\n \n )\n}\n\nfunction DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {\n return (\n \n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: DialogPrimitive.Description.Props) {\n return (\n \n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/dialog/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/direction.json b/public/r/react/styles/base-luma/direction.json new file mode 100644 index 000000000..b4a484295 --- /dev/null +++ b/public/r/react/styles/base-luma/direction.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "direction", + "title": "Direction", + "description": "Sets the text direction for the components inside it.", + "dependencies": [ + "@base-ui/react" + ], + "files": [ + { + "path": "src/components/ui/direction.tsx", + "content": "\"use client\"\n\nexport {\n DirectionProvider,\n useDirection,\n} from \"@base-ui/react/direction-provider\"\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/direction/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/doc-1.json b/public/r/react/styles/base-luma/doc-1.json new file mode 100644 index 000000000..c5e5a5d92 --- /dev/null +++ b/public/r/react/styles/base-luma/doc-1.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "doc-1", + "title": "Doc 1", + "description": "Documentation page shells for component pages with content, table of contents, and contextual links.", + "dependencies": [ + "cn", + "lucide-react", + "simple-icons" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/dropdown-menu", + "@fulldev/section", + "@fulldev/toc", + "@fulldev/typography" + ], + "files": [ + { + "path": "src/components/blocks/doc-1.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\nimport {\n ArrowLeftIcon,\n ArrowRightIcon,\n CheckIcon,\n ChevronDownIcon,\n CopyIcon,\n ExternalLinkIcon,\n} from \"lucide-react\"\nimport { siClaude, siCursor, siMarkdown, type SimpleIcon } from \"simple-icons\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport {\n Card,\n CardDescription,\n CardFooter,\n CardHeader,\n} from \"@/components/ui/card\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\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\n// Copies text and shows a check for a moment; a failed copy can be retried.\nfunction useCopy() {\n const [copied, setCopied] = React.useState(false)\n React.useEffect(() => {\n if (!copied) return\n const timeout = setTimeout(() => setCopied(false), 1200)\n return () => clearTimeout(timeout)\n }, [copied])\n const copy = (text: string) =>\n navigator.clipboard.writeText(text).then(\n () => setCopied(true),\n () => {}\n )\n return { copied, copy }\n}\n\nfunction BrandIcon({ icon }: { icon: SimpleIcon }) {\n return (\n \n \n \n )\n}\n\nfunction ChatGPTIcon() {\n return (\n \n \n \n )\n}\n\n// One callback ref for several refs. A callback ref's own cleanup runs when\n// the node detaches (React 19); other refs are set back to null.\nfunction composeRefs(...refs: (React.Ref | undefined)[]) {\n return (node: T | null) => {\n const cleanups = refs.map((ref) => {\n if (typeof ref === \"function\") {\n const cleanup = ref(node)\n return typeof cleanup === \"function\" ? cleanup : () => ref(null)\n }\n if (ref) {\n ref.current = node\n return () => {\n ref.current = null\n }\n }\n })\n return () => cleanups.forEach((cleanup) => cleanup?.())\n }\n}\n\nconst CopyLabelContext = React.createContext(\"Copy code\")\n\n// A code block with a copy button. Doc1 uses it for the
 elements it\n// gets as direct children. Content from a component, such as compiled MDX,\n// renders its own 
, so map it there: .\nfunction Doc1CodeBlock({\n  className,\n  ref,\n  ...props\n}: React.ComponentProps<\"pre\">) {\n  const label = React.useContext(CopyLabelContext)\n  const pre = React.useRef(null)\n  const setPre = React.useMemo(() => composeRefs(pre, ref), [ref])\n  const { copied, copy } = useCopy()\n  return (\n    \n      \n       copy(pre.current?.textContent?.replace(/\\n$/, \"\") ?? \"\")}\n        className=\"absolute top-3 right-3 z-10 inline-flex size-8 items-center justify-center rounded-md border bg-background text-muted-foreground shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring [&_svg]:size-4\"\n      >\n        {copied ?  : }\n      \n    \n  )\n}\n\nfunction Doc1({\n  className,\n  title,\n  description,\n  copyButton,\n  markdownUrl,\n  tocItems,\n  callout,\n  previousPage,\n  nextPage,\n  labels,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & {\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    }\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    assistantPrompt: string\n    copyCode: string\n    pagination: string\n    toc: string\n  }\n}) {\n  const { copied, copy } = useCopy()\n  const prompt = encodeURIComponent(labels.assistantPrompt)\n  const openLinks = markdownUrl\n    ? [\n        {\n          label: labels.openInMarkdown,\n          href: markdownUrl,\n          icon: ,\n        },\n        {\n          label: labels.openInChatGPT,\n          href: `https://chatgpt.com/?hints=search&q=${prompt}`,\n          icon: ,\n        },\n        {\n          label: labels.openInClaude,\n          href: `https://claude.ai/new?q=${prompt}`,\n          icon: ,\n        },\n        {\n          label: labels.openInCursor,\n          href: `https://cursor.com/link/prompt?text=${prompt}`,\n          icon: ,\n        },\n      ]\n    : []\n\n  return (\n    \n      
\n
\n
\n \n {title}\n \n \n {description}\n \n
\n
\n {copyButton && (\n copy(copyButton.source)}\n >\n {copied ? (\n \n ) : (\n \n )}\n {labels.copyMarkdown}\n \n )}\n {openLinks.length > 0 && (\n \n \n {labels.openIn}\n \n \n \n \n {openLinks.map((link) => (\n \n }\n >\n {link.icon}\n {link.label}\n \n \n ))}\n \n \n \n )}\n
\n
\n\n \n } size=\"sm\">\n {React.Children.map(children, (child) =>\n React.isValidElement>(child) &&\n child.type === \"pre\" ? (\n \n ) : (\n child\n )\n )}\n \n \n\n {(previousPage || nextPage) && (\n \n {previousPage ? (\n \n \n \n {previousPage.title}\n \n \n ) : (\n
\n )}\n {nextPage ? (\n \n \n {nextPage.title}\n \n \n \n ) : (\n
\n )}\n \n )}\n
\n\n {(tocItems.length > 0 || callout) && (\n
\n
\n {tocItems.length > 0 && (\n \n {labels.toc}\n \n {tocItems.map((item) => (\n \n \n {item.label}\n \n \n ))}\n \n \n )}\n {callout && (\n \n \n {callout.description}\n \n \n \n {callout.button.label}\n \n \n \n )}\n
\n
\n )}\n \n )\n}\n\nexport { Doc1, Doc1CodeBlock }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/doc/", + "categories": [ + "doc" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/drawer-examples.json b/public/r/react/styles/base-luma/drawer-examples.json new file mode 100644 index 000000000..4ed7ded39 --- /dev/null +++ b/public/r/react/styles/base-luma/drawer-examples.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "drawer-examples", + "title": "Drawer examples", + "description": "The examples from the shadcn/ui Drawer docs.", + "dependencies": [ + "cn", + "sonner" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/dialog", + "@fulldev/drawer", + "@fulldev/field", + "@fulldev/input", + "@fulldev/label", + "@fulldev/radio-group", + "@fulldev/use-mobile" + ], + "files": [ + { + "path": "src/components/examples/drawer/drawer-demo.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport { useIsMobile } from \"@/hooks/use-mobile\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/components/ui/drawer\"\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldLabel,\n FieldTitle,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n\nconst deliveryTimes = [\n {\n value: \"asap\",\n id: \"delivery-asap\",\n label: \"Standard delivery\",\n description: \"25–35 min · Driver assigned now\",\n badge: \"Fastest\",\n },\n {\n value: \"5-00\",\n id: \"delivery-5-00\",\n label: \"5:00 PM – 5:15 PM\",\n description: \"Prep starts at 4:45 PM\",\n },\n {\n value: \"5-30\",\n id: \"delivery-5-30\",\n label: \"5:30 PM – 5:45 PM\",\n description: \"Good if you're heading home\",\n },\n {\n value: \"6-00\",\n id: \"delivery-6-00\",\n label: \"6:00 PM – 6:15 PM\",\n description: \"Most popular · High demand\",\n },\n {\n value: \"6-30\",\n id: \"delivery-6-30\",\n label: \"6:30 PM – 6:45 PM\",\n description: \"Last slot before kitchen closes\",\n },\n]\n\nexport function DrawerDemo() {\n const [open, setOpen] = React.useState(false)\n const [deliveryTime, setDeliveryTime] = React.useState(\"asap\")\n const isMobile = useIsMobile()\n\n function handleConfirm() {\n const selected = deliveryTimes.find((time) => time.value === deliveryTime)\n\n if (!selected) {\n return\n }\n\n setOpen(false)\n toast(\"Delivery time confirmed\", {\n description: selected.label,\n })\n }\n\n return (\n \n }>\n Open Drawer\n \n \n \n Pick a delivery time\n \n We'll prepare your order as soon as possible.\n \n \n
\n \n {deliveryTimes.map((time) => (\n \n \n \n \n {time.label}\n {time.badge ? (\n {time.badge}\n ) : null}\n \n {time.description}\n \n \n \n \n ))}\n \n
\n \n \n }>\n Cancel\n \n \n
\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-dialog.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { useMediaQuery } from \"@/hooks/use-media-query\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/components/ui/drawer\"\nimport { Input } from \"@/components/ui/input\"\nimport { Label } from \"@/components/ui/label\"\n\nexport function DrawerDialogDemo() {\n const [open, setOpen] = React.useState(false)\n const isDesktop = useMediaQuery(\"(min-width: 768px)\")\n\n if (isDesktop) {\n return (\n \n }>\n Edit Profile\n \n \n \n Edit profile\n \n Make changes to your profile here. Click save when you're\n done.\n \n \n \n \n \n )\n }\n\n return (\n \n }>\n Edit Profile\n \n \n \n Edit profile\n \n Make changes to your profile here. Click save when you're done.\n \n \n \n \n \n )\n}\n\nfunction ProfileForm({ className }: React.ComponentProps<\"form\">) {\n return (\n
\n
\n \n \n
\n
\n \n \n
\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-nested.tsx", + "content": "\"use client\"\n\nimport { useIsMobile } from \"@/hooks/use-mobile\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/components/ui/drawer\"\n\nexport function DrawerNested() {\n const isMobile = useIsMobile()\n\n const swipeDirection = isMobile ? \"down\" : \"right\"\n\n return (\n \n }>\n Open Drawer\n \n \n \n Drawer\n \n Open another drawer from the same direction.\n \n \n
\n
\n
\n \n \n }>\n Open Nested Drawer\n \n \n \n Nested Drawer\n \n The parent drawer stays mounted behind this one.\n \n \n
\n
\n
\n \n \n }>\n Open Third Drawer\n \n \n \n Third Drawer\n \n Two drawers are stacked behind this one.\n \n \n
\n
\n
\n \n \n }>\n Open Fourth Drawer\n \n \n \n Fourth Drawer\n \n This is the frontmost drawer in the stack.\n \n \n
\n
\n
\n \n }>\n Close\n \n \n \n \n }>\n Close\n \n \n \n \n }>\n Close\n \n \n \n \n }>Close\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-non-modal.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/components/ui/drawer\"\n\nexport function DrawerNonModal() {\n return (\n \n }>\n Non Modal\n \n \n \n Non Modal Drawer\n \n
\n
\n
\n \n }>Close\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-sides.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/components/ui/drawer\"\n\nexport function DrawerWithSides() {\n return (\n \n }>\n Open Left Drawer\n \n \n \n Move Goal\n Set your daily activity goal.\n \n
\n
\n
\n \n }>Close\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-snap-points.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/components/ui/drawer\"\n\nconst SNAP_POINTS = [\"31rem\", 1]\n\nexport function DrawerSnapPoints() {\n return (\n \n }>\n Open Snap Drawer\n \n \n \n Snap points\n \n Drag the drawer to snap between a compact peek and a near\n full-height view.\n \n \n
\n
\n
\n \n }>Close\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-swipe-handle.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/components/ui/drawer\"\n\nexport function DrawerSwipeHandle() {\n return (\n \n }>\n Open Drawer\n \n \n \n Drawer\n Drawer with a swipe handle.\n \n
\n
\n
\n \n }>Close\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/hooks/use-media-query.tsx", + "content": "import * as React from \"react\"\n\nexport function useMediaQuery(query: string) {\n const [value, setValue] = React.useState(false)\n\n React.useEffect(() => {\n function onChange(event: MediaQueryListEvent) {\n setValue(event.matches)\n }\n\n const result = matchMedia(query)\n result.addEventListener(\"change\", onChange)\n setValue(result.matches)\n\n return () => result.removeEventListener(\"change\", onChange)\n }, [query])\n\n return value\n}\n", + "type": "registry:hook" + } + ], + "docs": "https://ui.full.dev/react/components/drawer/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/drawer.json b/public/r/react/styles/base-luma/drawer.json new file mode 100644 index 000000000..bed15960c --- /dev/null +++ b/public/r/react/styles/base-luma/drawer.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "drawer", + "title": "Drawer", + "description": "A swipeable panel that opens from an edge of the screen.", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/drawer.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Drawer as DrawerPrimitive } from \"@base-ui/react/drawer\"\nimport { cn } from \"cn\"\n\ntype DrawerContextProps = {\n hasSnapPoints: boolean\n modal: DrawerPrimitive.Root.Props[\"modal\"]\n showSwipeHandle: boolean\n swipeDirection: NonNullable\n}\n\nconst DrawerContext = React.createContext(null)\n\nfunction useDrawer() {\n const context = React.useContext(DrawerContext)\n\n if (!context) {\n throw new Error(\"useDrawer must be used within a Drawer.\")\n }\n\n return context\n}\n\nfunction Drawer({\n modal = true,\n showSwipeHandle = false,\n snapPoints,\n swipeDirection = \"down\",\n ...props\n}: DrawerPrimitive.Root.Props & {\n showSwipeHandle?: boolean\n}) {\n const hasSnapPoints = snapPoints != null && snapPoints.length > 0\n const contextValue = React.useMemo(\n () => ({ hasSnapPoints, modal, showSwipeHandle, swipeDirection }),\n [hasSnapPoints, modal, showSwipeHandle, swipeDirection]\n )\n\n return (\n \n \n \n )\n}\n\nfunction DrawerTrigger({ ...props }: DrawerPrimitive.Trigger.Props) {\n return \n}\n\nfunction DrawerPortal({ ...props }: DrawerPrimitive.Portal.Props) {\n return \n}\n\nfunction DrawerClose({ ...props }: DrawerPrimitive.Close.Props) {\n return \n}\n\nfunction DrawerOverlay({\n className,\n ...props\n}: DrawerPrimitive.Backdrop.Props) {\n return (\n \n )\n}\n\nfunction DrawerSwipeHandle({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction DrawerViewport({\n className,\n ...props\n}: DrawerPrimitive.Viewport.Props) {\n const { modal } = useDrawer()\n return (\n \n )\n}\n\nfunction DrawerPopup({ className, ...props }: DrawerPrimitive.Popup.Props) {\n const { hasSnapPoints, swipeDirection } = useDrawer()\n const swipeAxis =\n swipeDirection === \"down\" || swipeDirection === \"up\" ? \"y\" : \"x\"\n return (\n \n )\n}\n\nfunction DrawerContent({\n className,\n children,\n ...props\n}: DrawerPrimitive.Popup.Props) {\n const { hasSnapPoints, modal, showSwipeHandle } = useDrawer()\n\n return (\n \n {modal === true && (\n \n )}\n \n \n {showSwipeHandle && }\n {/* Long content scrolls inside the drawer. */}\n \n {children}\n \n \n \n \n )\n}\n\n// Lets a page outside the drawer react to it: wrap the app in DrawerProvider\n// and the page in DrawerIndent, with DrawerIndentBackground behind it.\nfunction DrawerProvider(props: DrawerPrimitive.Provider.Props) {\n return \n}\n\nfunction DrawerIndent({ ...props }: DrawerPrimitive.Indent.Props) {\n return \n}\n\nfunction DrawerIndentBackground({\n ...props\n}: DrawerPrimitive.IndentBackground.Props) {\n return (\n \n )\n}\n\n// Keeps a focused input above the on-screen keyboard on touch devices.\nfunction DrawerVirtualKeyboardProvider(\n props: DrawerPrimitive.VirtualKeyboardProvider.Props\n) {\n return \n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction DrawerTitle({ className, ...props }: DrawerPrimitive.Title.Props) {\n return (\n \n )\n}\n\nfunction DrawerDescription({\n className,\n ...props\n}: DrawerPrimitive.Description.Props) {\n return (\n \n )\n}\n\nexport {\n Drawer,\n DrawerPortal,\n DrawerOverlay,\n DrawerViewport,\n DrawerPopup,\n DrawerProvider,\n DrawerIndent,\n DrawerIndentBackground,\n DrawerVirtualKeyboardProvider,\n DrawerSwipeHandle,\n DrawerTrigger,\n DrawerClose,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/drawer/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/dropdown-menu-examples.json b/public/r/react/styles/base-luma/dropdown-menu-examples.json new file mode 100644 index 000000000..2118ded2d --- /dev/null +++ b/public/r/react/styles/base-luma/dropdown-menu-examples.json @@ -0,0 +1,90 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "dropdown-menu-examples", + "title": "Dropdown Menu examples", + "description": "The examples from the shadcn/ui Dropdown Menu docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-avatar.tsx", + "content": "\"use client\"\n\nimport {\n BadgeCheckIcon,\n BellIcon,\n CreditCardIcon,\n LogOutIcon,\n} from \"lucide-react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuAvatar() {\n return (\n \n }\n >\n \n \n LR\n \n \n \n \n \n \n Account\n \n \n \n Billing\n \n \n \n Notifications\n \n \n \n \n \n Sign Out\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-basic.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuBasic() {\n return (\n \n }>\n Open\n \n \n \n My Account\n Profile\n Billing\n Settings\n \n \n GitHub\n Support\n API\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-checkboxes-icons.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { BellIcon, MailIcon, MessageSquareIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuCheckboxesIcons() {\n const [notifications, setNotifications] = React.useState({\n email: true,\n sms: false,\n push: true,\n })\n\n return (\n \n }>\n Notifications\n \n \n \n Notification Preferences\n \n setNotifications({ ...notifications, email: checked === true })\n }\n >\n \n Email notifications\n \n \n setNotifications({ ...notifications, sms: checked === true })\n }\n >\n \n SMS notifications\n \n \n setNotifications({ ...notifications, push: checked === true })\n }\n >\n \n Push notifications\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-checkboxes.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuCheckboxes() {\n const [showStatusBar, setShowStatusBar] = React.useState(true)\n const [showActivityBar, setShowActivityBar] = React.useState(false)\n const [showPanel, setShowPanel] = React.useState(false)\n\n return (\n \n }>\n Open\n \n \n \n Appearance\n \n Status Bar\n \n \n Activity Bar\n \n \n Panel\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-complex.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n BellIcon,\n CreditCardIcon,\n DownloadIcon,\n EyeIcon,\n FileCodeIcon,\n FileIcon,\n FileTextIcon,\n FolderIcon,\n FolderOpenIcon,\n FolderSearchIcon,\n HelpCircleIcon,\n KeyboardIcon,\n LanguagesIcon,\n LayoutIcon,\n LogOutIcon,\n MailIcon,\n MonitorIcon,\n MoonIcon,\n MoreHorizontalIcon,\n PaletteIcon,\n SaveIcon,\n SettingsIcon,\n ShieldIcon,\n SunIcon,\n UserIcon,\n} from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuComplex() {\n const [notifications, setNotifications] = React.useState({\n email: true,\n sms: false,\n push: true,\n })\n const [theme, setTheme] = React.useState(\"light\")\n\n return (\n \n }>\n Complex Menu\n \n \n \n File\n \n \n New File\n ⌘N\n \n \n \n New Folder\n ⇧⌘N\n \n \n \n \n Open Recent\n \n \n \n \n Recent Projects\n \n \n Project Alpha\n \n \n \n Project Beta\n \n \n \n \n More Projects\n \n \n \n \n \n Project Gamma\n \n \n \n Project Delta\n \n \n \n \n \n \n \n \n \n Browse...\n \n \n \n \n \n \n \n \n Save\n ⌘S\n \n \n \n Export\n ⇧⌘E\n \n \n \n \n View\n \n setNotifications({ ...notifications, email: checked === true })\n }\n >\n \n Show Sidebar\n \n \n setNotifications({ ...notifications, sms: checked === true })\n }\n >\n \n Show Status Bar\n \n \n \n \n Theme\n \n \n \n \n Appearance\n \n \n \n Light\n \n \n \n Dark\n \n \n \n System\n \n \n \n \n \n \n \n \n \n Account\n \n \n Profile\n ⇧⌘P\n \n \n \n Billing\n \n \n \n \n Settings\n \n \n \n \n Preferences\n \n \n Keyboard Shortcuts\n \n \n \n Language\n \n \n \n \n Notifications\n \n \n \n \n \n Notification Types\n \n \n setNotifications({\n ...notifications,\n push: checked === true,\n })\n }\n >\n \n Push Notifications\n \n \n setNotifications({\n ...notifications,\n email: checked === true,\n })\n }\n >\n \n Email Notifications\n \n \n \n \n \n \n \n \n \n \n Privacy & Security\n \n \n \n \n \n \n \n \n \n \n Help & Support\n \n \n \n Documentation\n \n \n \n \n \n \n Sign Out\n ⇧⌘Q\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-demo.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuDemo() {\n return (\n \n }>\n Open\n \n \n \n My Account\n \n Profile\n ⇧⌘P\n \n \n Billing\n ⌘B\n \n \n Settings\n ⌘S\n \n \n \n \n Team\n \n Invite users\n \n \n Email\n Message\n \n More...\n \n \n \n \n New Team\n ⌘+T\n \n \n \n \n GitHub\n Support\n API\n \n \n \n \n Log out\n ⇧⌘Q\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-destructive.tsx", + "content": "\"use client\"\n\nimport { PencilIcon, ShareIcon, TrashIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuDestructive() {\n return (\n \n }>\n Actions\n \n \n \n \n \n Edit\n \n \n \n Share\n \n \n \n \n \n \n Delete\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-icons.tsx", + "content": "\"use client\"\n\nimport {\n CreditCardIcon,\n LogOutIcon,\n SettingsIcon,\n UserIcon,\n} from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuIcons() {\n return (\n \n }>\n Open\n \n \n \n \n Profile\n \n \n \n Billing\n \n \n \n Settings\n \n \n \n \n Log out\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-radio-group.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuRadioGroupDemo() {\n const [position, setPosition] = React.useState(\"bottom\")\n\n return (\n \n }>\n Open\n \n \n \n Panel Position\n \n Top\n Bottom\n Right\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-radio-icons.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Building2Icon, CreditCardIcon, WalletIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuRadioIcons() {\n const [paymentMethod, setPaymentMethod] = React.useState(\"card\")\n\n return (\n \n }>\n Payment Method\n \n \n \n Select Payment Method\n \n \n \n Credit Card\n \n \n \n PayPal\n \n \n \n Bank Transfer\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { CreditCardIcon, SettingsIcon, UserIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n open: \"Open\",\n account: \"Account\",\n profile: \"Profile\",\n billing: \"Billing\",\n settings: \"Settings\",\n logout: \"Log out\",\n team: \"Team\",\n inviteUsers: \"Invite users\",\n email: \"Email\",\n message: \"Message\",\n more: \"More\",\n calendar: \"Calendar\",\n chat: \"Chat\",\n webhook: \"Webhook\",\n advanced: \"Advanced...\",\n newTeam: \"New Team\",\n view: \"View\",\n statusBar: \"Status Bar\",\n activityBar: \"Activity Bar\",\n panel: \"Panel\",\n position: \"Position\",\n top: \"Top\",\n bottom: \"Bottom\",\n right: \"Right\",\n left: \"Left\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n open: \"افتح القائمة\",\n account: \"الحساب\",\n profile: \"الملف الشخصي\",\n billing: \"الفوترة\",\n settings: \"الإعدادات\",\n logout: \"تسجيل الخروج\",\n team: \"الفريق\",\n inviteUsers: \"دعوة المستخدمين\",\n email: \"البريد الإلكتروني\",\n message: \"رسالة\",\n more: \"المزيد\",\n calendar: \"تقويم\",\n chat: \"دردشة\",\n webhook: \"خطاف ويب\",\n advanced: \"متقدم...\",\n newTeam: \"فريق جديد\",\n view: \"عرض\",\n statusBar: \"شريط الحالة\",\n activityBar: \"شريط النشاط\",\n panel: \"اللوحة\",\n position: \"الموضع\",\n top: \"أعلى\",\n bottom: \"أسفل\",\n right: \"يمين\",\n left: \"يسار\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n open: \"פתח תפריט\",\n account: \"חשבון\",\n profile: \"פרופיל\",\n billing: \"חיוב\",\n settings: \"הגדרות\",\n logout: \"התנתק\",\n team: \"הצוות\",\n inviteUsers: \"הזמן משתמשים\",\n email: \"אימייל\",\n message: \"הודעה\",\n more: \"עוד\",\n calendar: \"יומן\",\n chat: \"צ'אט\",\n webhook: \"Webhook\",\n advanced: \"מתקדם...\",\n newTeam: \"צוות חדש\",\n view: \"תצוגה\",\n statusBar: \"שורת סטטוס\",\n activityBar: \"שורת פעילות\",\n panel: \"לוח\",\n position: \"מיקום\",\n top: \"למעלה\",\n bottom: \"למטה\",\n right: \"ימין\",\n left: \"שמאל\",\n },\n },\n}\n\nexport function DropdownMenuRtl() {\n const { dir, language, t } = useTranslation(translations, \"ar\")\n const [showStatusBar, setShowStatusBar] = React.useState(true)\n const [showActivityBar, setShowActivityBar] = React.useState(false)\n const [showPanel, setShowPanel] = React.useState(false)\n const [position, setPosition] = React.useState(\"bottom\")\n\n return (\n \n }>\n {t.open}\n \n \n \n \n {t.account}\n \n \n \n \n \n {t.profile}\n \n \n \n {t.billing}\n \n \n \n {t.settings}\n \n \n \n \n \n \n \n \n {t.team}\n {t.team}\n \n {t.inviteUsers}\n \n \n {t.email}\n {t.message}\n \n {t.more}\n \n \n {t.calendar}\n {t.chat}\n \n {t.webhook}\n \n \n \n \n {t.advanced}\n \n \n \n \n {t.newTeam}\n ⌘+T\n \n \n \n \n {t.view}\n \n {t.statusBar}\n \n \n {t.activityBar}\n \n \n {t.panel}\n \n \n \n \n {t.position}\n \n {t.top}\n \n {t.bottom}\n \n \n {t.right}\n \n {t.left}\n \n \n \n \n {t.logout}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-shortcuts.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuShortcuts() {\n return (\n \n }>\n Open\n \n \n \n My Account\n \n Profile\n ⇧⌘P\n \n \n Billing\n ⌘B\n \n \n Settings\n ⌘S\n \n \n \n \n Log out\n ⇧⌘Q\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-submenu.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuPortal,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function DropdownMenuSubmenu() {\n return (\n \n }>\n Open\n \n \n \n Team\n \n Invite users\n \n \n Email\n Message\n \n More options\n \n \n Calendly\n Slack\n \n Webhook\n \n \n \n \n Advanced...\n \n \n \n \n New Team\n ⌘+T\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/dropdown-menu/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/dropdown-menu.json b/public/r/react/styles/base-luma/dropdown-menu.json new file mode 100644 index 000000000..cd8fb3378 --- /dev/null +++ b/public/r/react/styles/base-luma/dropdown-menu.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "dropdown-menu", + "title": "Dropdown Menu", + "description": "Displays a menu to the user, such as a set of actions or functions, triggered by a button.", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/dropdown-menu.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\"\nimport { cn } from \"cn\"\nimport { CheckIcon, ChevronRightIcon } from \"lucide-react\"\n\nfunction DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {\n return \n}\n\nfunction DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {\n return \n}\n\nfunction DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {\n return \n}\n\nfunction DropdownMenuContent({\n align = \"start\",\n alignOffset = 0,\n side = \"bottom\",\n sideOffset = 4,\n className,\n ...props\n}: MenuPrimitive.Popup.Props &\n Pick<\n MenuPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n \n \n \n \n \n )\n}\n\nfunction DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {\n return \n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: MenuPrimitive.GroupLabel.Props & {\n inset?: boolean\n}) {\n return (\n \n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: MenuPrimitive.Item.Props & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n \n )\n}\n\nfunction DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {\n return \n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: MenuPrimitive.SubmenuTrigger.Props & {\n inset?: boolean\n}) {\n return (\n \n {children}\n \n \n )\n}\n\nfunction DropdownMenuSubContent({\n align = \"start\",\n alignOffset = -3,\n side = \"right\",\n sideOffset = 0,\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n inset,\n ...props\n}: MenuPrimitive.CheckboxItem.Props & {\n inset?: boolean\n}) {\n return (\n \n \n \n \n \n \n {children}\n \n )\n}\n\nfunction DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {\n return (\n \n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n inset,\n ...props\n}: MenuPrimitive.RadioItem.Props & {\n inset?: boolean\n}) {\n return (\n \n \n \n \n \n \n {children}\n \n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: MenuPrimitive.Separator.Props) {\n return (\n \n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n \n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/dropdown-menu/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/empty-examples.json b/public/r/react/styles/base-luma/empty-examples.json new file mode 100644 index 000000000..c4999988f --- /dev/null +++ b/public/r/react/styles/base-luma/empty-examples.json @@ -0,0 +1,63 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "empty-examples", + "title": "Empty examples", + "description": "The examples from the shadcn/ui Empty docs.", + "dependencies": [ + "@tabler/icons-react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/empty", + "@fulldev/input-group", + "@fulldev/kbd", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/empty/empty-avatar-group.tsx", + "content": "import { PlusIcon } from \"lucide-react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/components/ui/empty\"\n\nexport function EmptyAvatarGroup() {\n return (\n \n \n \n
\n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n
\n
\n No Team Members\n \n Invite your team to collaborate on this project.\n \n
\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-avatar.tsx", + "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/components/ui/empty\"\n\nexport function EmptyAvatar() {\n return (\n \n \n \n \n \n LR\n \n \n User Offline\n \n This user is currently offline. You can leave a message to notify them\n or try again later.\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-background.tsx", + "content": "import { IconBell } from \"@tabler/icons-react\"\nimport { RefreshCcwIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/components/ui/empty\"\n\nexport function EmptyMuted() {\n return (\n \n \n \n \n \n No Notifications\n \n You're all caught up. New notifications will appear here.\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-demo.tsx", + "content": "import { IconFolderCode } from \"@tabler/icons-react\"\nimport { ArrowUpRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/components/ui/empty\"\n\nexport function EmptyDemo() {\n return (\n \n \n \n \n \n No Projects Yet\n \n You haven't created any projects yet. Get started by creating\n your first project.\n \n \n \n \n \n \n }\n className=\"text-muted-foreground\"\n size=\"sm\"\n nativeButton={false}\n >\n Learn More \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-input-group.tsx", + "content": "import { SearchIcon } from \"lucide-react\"\n\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyTitle,\n} from \"@/components/ui/empty\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport { Kbd } from \"@/components/ui/kbd\"\n\nexport function EmptyInputGroup() {\n return (\n \n \n 404 - Not Found\n \n The page you're looking for doesn't exist. Try searching for\n what you need below.\n \n \n \n \n \n \n \n \n \n /\n \n \n \n Need help? Contact support\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-outline.tsx", + "content": "import { IconCloud } from \"@tabler/icons-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/components/ui/empty\"\n\nexport function EmptyOutline() {\n return (\n \n \n \n \n \n Cloud Storage Empty\n \n Upload files to your cloud storage to access them anywhere.\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { IconFolderCode } from \"@tabler/icons-react\"\nimport { ArrowUpRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/components/ui/empty\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n title: \"No Projects Yet\",\n description:\n \"You haven't created any projects yet. Get started by creating your first project.\",\n createProject: \"Create Project\",\n importProject: \"Import Project\",\n learnMore: \"Learn More\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n title: \"لا توجد مشاريع بعد\",\n description: \"لم تقم بإنشاء أي مشاريع بعد. ابدأ بإنشاء مشروعك الأول.\",\n createProject: \"إنشاء مشروع\",\n importProject: \"استيراد مشروع\",\n learnMore: \"تعرف على المزيد\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n title: \"אין פרויקטים עדיין\",\n description:\n \"עדיין לא יצרת פרויקטים. התחל על ידי יצירת הפרויקט הראשון שלך.\",\n createProject: \"צור פרויקט\",\n importProject: \"ייבא פרויקט\",\n learnMore: \"למד עוד\",\n },\n },\n}\n\nexport function EmptyRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n \n \n \n \n \n {t.title}\n {t.description}\n \n \n \n \n \n }\n className=\"text-muted-foreground\"\n size=\"sm\"\n nativeButton={false}\n >\n {t.learnMore}{\" \"}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/empty/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/empty.json b/public/r/react/styles/base-luma/empty.json new file mode 100644 index 000000000..2d4b94bbe --- /dev/null +++ b/public/r/react/styles/base-luma/empty.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "empty", + "title": "Empty", + "description": "Displays an empty state placeholder with optional media, title, and description.", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/empty.tsx", + "content": "import { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nfunction Empty({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction EmptyHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nconst emptyMediaVariants = cva(\n \"mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n icon: \"bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-xl [&_svg:not([class*='size-'])]:size-5\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction EmptyMedia({\n className,\n variant = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps) {\n return (\n \n )\n}\n\nfunction EmptyTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction EmptyDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction EmptyContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nexport {\n Empty,\n EmptyHeader,\n EmptyTitle,\n EmptyDescription,\n EmptyContent,\n EmptyMedia,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/empty/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/faqs-1.json b/public/r/react/styles/base-luma/faqs-1.json new file mode 100644 index 000000000..97d2cebc8 --- /dev/null +++ b/public/r/react/styles/base-luma/faqs-1.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "faqs-1", + "title": "Faqs 1", + "description": "FAQ sections for product pages, launches, and documentation support content.", + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/faqs-1.tsx", + "content": "import * as React from \"react\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Faqs1({\n title,\n description,\n faqs,\n defaultItem,\n buttons,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n faqs: {\n id: string\n question: string\n answer: string\n }[]\n defaultItem?: string\n buttons?: {\n label: string\n href: string\n }[]\n}) {\n return (\n
\n \n
\n {title}\n {description}\n
\n {buttons && buttons.length > 0 && (\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n )}\n
\n \n
\n \n {faqs.map((item) => (\n \n {item.question}\n {item.answer}\n \n ))}\n \n
\n
\n
\n )\n}\n\nexport { Faqs1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/faqs/", + "categories": [ + "faqs" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/faqs-2.json b/public/r/react/styles/base-luma/faqs-2.json new file mode 100644 index 000000000..a22bd7477 --- /dev/null +++ b/public/r/react/styles/base-luma/faqs-2.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "faqs-2", + "title": "Faqs 2", + "description": "FAQ sections for product pages, launches, and documentation support content.", + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/faqs-2.tsx", + "content": "import * as React from \"react\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Faqs2({\n title,\n description,\n faqs,\n buttons,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n faqs: {\n id: string\n question: string\n answer: string\n }[]\n buttons: {\n label: string\n href: string\n }[]\n}) {\n return (\n
\n \n
\n
\n {title}\n

\n {description}\n

\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n
\n \n {faqs.map((item) => (\n \n {item.question}\n {item.answer}\n \n ))}\n \n
\n
\n
\n
\n )\n}\n\nexport { Faqs2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/faqs/", + "categories": [ + "faqs" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/faqs-3.json b/public/r/react/styles/base-luma/faqs-3.json new file mode 100644 index 000000000..242895e46 --- /dev/null +++ b/public/r/react/styles/base-luma/faqs-3.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "faqs-3", + "title": "Faqs 3", + "description": "FAQ sections for product pages, launches, and documentation support content.", + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/badge", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/faqs-3.tsx", + "content": "import * as React from \"react\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\nimport { Badge } from \"@/components/ui/badge\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Faqs3({\n badge,\n title,\n description,\n faqs,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n description: string\n faqs: {\n id: string\n question: string\n answer: string\n }[]\n}) {\n return (\n
\n \n
\n {badge}\n {title}\n

\n {description}\n

\n
\n
\n \n
\n \n {faqs.map((item) => (\n \n {item.question}\n {item.answer}\n \n ))}\n \n
\n
\n
\n )\n}\n\nexport { Faqs3 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/faqs/", + "categories": [ + "faqs" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/faqs-4.json b/public/r/react/styles/base-luma/faqs-4.json new file mode 100644 index 000000000..ca0038d84 --- /dev/null +++ b/public/r/react/styles/base-luma/faqs-4.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "faqs-4", + "title": "Faqs 4", + "description": "FAQ sections for product pages, launches, and documentation support content.", + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/faqs-4.tsx", + "content": "import * as React from \"react\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Faqs4({\n title,\n faqs,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n faqs: {\n id: string\n question: string\n answer: string\n }[]\n}) {\n return (\n
\n \n
\n {title}\n
\n \n {faqs.map((item) => (\n \n {item.question}\n {item.answer}\n \n ))}\n \n
\n
\n
\n
\n )\n}\n\nexport { Faqs4 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/faqs/", + "categories": [ + "faqs" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/features-1.json b/public/r/react/styles/base-luma/features-1.json new file mode 100644 index 000000000..9c7a31470 --- /dev/null +++ b/public/r/react/styles/base-luma/features-1.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "features-1", + "title": "Features 1", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/features-1.tsx", + "content": "import * as React from \"react\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Icon } from \"@/components/ui/icon\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Features1({\n title,\n description,\n buttons,\n features,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n features: {\n title: string\n description: string\n icon: string\n link?: {\n label: string\n href: string\n }\n }[]\n}) {\n return (\n
\n \n
\n {title}\n \n {description}\n \n
\n {buttons.length > 0 && (\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n )}\n
\n \n
    \n {features.map((feature) => (\n \n
    \n \n
    \n
    \n

    \n {feature.title}\n

    \n

    \n {feature.description}\n

    \n
    \n {feature.link && (\n \n {feature.link.label}\n \n \n )}\n \n ))}\n
\n
\n
\n )\n}\n\nexport { Features1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "categories": [ + "features" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/features-2.json b/public/r/react/styles/base-luma/features-2.json new file mode 100644 index 000000000..baad6b1d8 --- /dev/null +++ b/public/r/react/styles/base-luma/features-2.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "features-2", + "title": "Features 2", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "registryDependencies": [ + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/features-2.tsx", + "content": "import * as React from \"react\"\n\nimport { Icon } from \"@/components/ui/icon\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Features2({\n title,\n description,\n features,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n features: {\n title: string\n description: string\n icon: string\n }[]\n}) {\n return (\n
\n \n
\n {title}\n \n {description}\n \n
\n
\n \n
    \n {features.map((feature) => (\n \n
    \n \n
    \n

    \n {feature.title}\n

    \n

    \n {feature.description}\n

    \n \n ))}\n
\n
\n
\n )\n}\n\nexport { Features2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "categories": [ + "features" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/features-3.json b/public/r/react/styles/base-luma/features-3.json new file mode 100644 index 000000000..1afcdc5e3 --- /dev/null +++ b/public/r/react/styles/base-luma/features-3.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "features-3", + "title": "Features 3", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "registryDependencies": [ + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/features-3.tsx", + "content": "import * as React from \"react\"\n\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Features3({\n title,\n description,\n features,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n features: {\n title: string\n description: string\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n }[]\n}) {\n return (\n
\n \n
\n {title}\n \n {description}\n \n
\n
\n \n
    \n {features.map((feature) => (\n \n \n
    \n

    \n {feature.title}\n

    \n

    \n {feature.description}\n

    \n
    \n \n ))}\n
\n
\n
\n )\n}\n\nexport { Features3 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "categories": [ + "features" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/features-4.json b/public/r/react/styles/base-luma/features-4.json new file mode 100644 index 000000000..2129b1839 --- /dev/null +++ b/public/r/react/styles/base-luma/features-4.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "features-4", + "title": "Features 4", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/features-4.tsx", + "content": "import * as React from \"react\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Icon } from \"@/components/ui/icon\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Features4({\n title,\n description,\n buttons,\n features,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n features: {\n title: string\n description: string\n icon: string\n link?: {\n label: string\n href: string\n }\n }[]\n}) {\n return (\n
\n \n
\n
\n {title}\n

\n {description}\n

\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n
    \n {features.map((feature) => (\n \n
    \n \n
    \n
    \n

    \n {feature.title}\n

    \n

    \n {feature.description}\n

    \n
    \n {feature.link && (\n \n {feature.link.label}\n \n \n )}\n \n ))}\n
\n
\n
\n
\n )\n}\n\nexport { Features4 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "categories": [ + "features" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/features-5.json b/public/r/react/styles/base-luma/features-5.json new file mode 100644 index 000000000..7177dfea0 --- /dev/null +++ b/public/r/react/styles/base-luma/features-5.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "features-5", + "title": "Features 5", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "registryDependencies": [ + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/features-5.tsx", + "content": "import * as React from \"react\"\n\nimport { Icon } from \"@/components/ui/icon\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Features5({\n title,\n description,\n features,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n features: {\n title: string\n description: string\n icon: string\n }[]\n}) {\n return (\n
\n \n
\n {title}\n \n {description}\n \n
\n
\n \n
    \n {features.map((feature) => (\n \n
    \n \n
    \n

    \n {feature.title}\n

    \n

    \n {feature.description}\n

    \n \n ))}\n
\n
\n
\n )\n}\n\nexport { Features5 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "categories": [ + "features" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/features-6.json b/public/r/react/styles/base-luma/features-6.json new file mode 100644 index 000000000..a2fdbe3fa --- /dev/null +++ b/public/r/react/styles/base-luma/features-6.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "features-6", + "title": "Features 6", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/features-6.tsx", + "content": "import * as React from \"react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction Features6({\n title,\n description,\n buttons,\n features,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n features: {\n title: string\n description: string\n }[]\n}) {\n return (\n
\n \n
\n {title}\n

\n {description}\n

\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n
\n \n
    \n {features.map((feature) => (\n
  • \n \n
    \n

    \n {feature.title}\n

    \n

    \n {feature.description}\n

    \n
    \n
  • \n ))}\n
\n
\n
\n )\n}\n\nexport { Features6 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "categories": [ + "features" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/field-examples.json b/public/r/react/styles/base-luma/field-examples.json new file mode 100644 index 000000000..f482c04cf --- /dev/null +++ b/public/r/react/styles/base-luma/field-examples.json @@ -0,0 +1,94 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "field-examples", + "title": "Field examples", + "description": "The examples from the shadcn/ui Field docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/checkbox", + "@fulldev/field", + "@fulldev/input", + "@fulldev/radio-group", + "@fulldev/select", + "@fulldev/slider", + "@fulldev/switch", + "@fulldev/textarea" + ], + "files": [ + { + "path": "src/components/examples/field/field-checkbox.tsx", + "content": "import { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n} from \"@/components/ui/field\"\n\nexport function FieldCheckbox() {\n return (\n \n
\n \n Show these items on the desktop\n \n \n Select the items you want to show on the desktop.\n \n \n \n \n \n Hard disks\n \n \n \n \n \n External disks\n \n \n \n \n \n CDs, DVDs, and iPods\n \n \n \n \n \n Connected servers\n \n \n \n
\n \n \n \n \n \n Sync Desktop & Documents folders\n \n \n Your Desktop & Documents folders are being synced with iCloud Drive.\n You can access them from other devices.\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-choice-card.tsx", + "content": "import {\n Field,\n FieldContent,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSet,\n FieldTitle,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n\nexport function FieldChoiceCard() {\n return (\n \n
\n Compute Environment\n \n Select the compute environment for your cluster.\n \n \n \n \n \n Kubernetes\n \n Run GPU workloads on a K8s cluster.\n \n \n \n \n \n \n \n \n Virtual Machine\n \n Access a cluster to run GPU workloads.\n \n \n \n \n \n \n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-demo.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\nimport { Textarea } from \"@/components/ui/textarea\"\n\nconst months = [\n { label: \"MM\", value: null },\n { label: \"01\", value: \"01\" },\n { label: \"02\", value: \"02\" },\n { label: \"03\", value: \"03\" },\n { label: \"04\", value: \"04\" },\n { label: \"05\", value: \"05\" },\n { label: \"06\", value: \"06\" },\n { label: \"07\", value: \"07\" },\n { label: \"08\", value: \"08\" },\n { label: \"09\", value: \"09\" },\n { label: \"10\", value: \"10\" },\n { label: \"11\", value: \"11\" },\n { label: \"12\", value: \"12\" },\n]\n\nconst years = [\n { label: \"YYYY\", value: null },\n { label: \"2024\", value: \"2024\" },\n { label: \"2025\", value: \"2025\" },\n { label: \"2026\", value: \"2026\" },\n { label: \"2027\", value: \"2027\" },\n { label: \"2028\", value: \"2028\" },\n { label: \"2029\", value: \"2029\" },\n]\n\nexport function FieldDemo() {\n return (\n
\n
\n \n
\n Payment Method\n \n All transactions are secure and encrypted\n \n \n \n \n Name on Card\n \n \n \n \n \n Card Number\n \n \n \n Enter your 16-digit card number\n \n \n
\n \n \n Month\n \n \n \n \n \n Year\n \n \n \n \n CVV\n \n \n
\n
\n
\n \n
\n Billing Address\n \n The billing address associated with your payment method\n \n \n \n \n \n Same as shipping address\n \n \n \n
\n
\n \n \n \n Comments\n \n \n \n \n
\n \n \n \n \n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-fieldset.tsx", + "content": "import {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function FieldFieldset() {\n return (\n
\n Address Information\n \n We need your address to deliver your order.\n \n \n \n Street Address\n \n \n
\n \n City\n \n \n \n Postal Code\n \n \n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-group.tsx", + "content": "import { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldSeparator,\n FieldSet,\n} from \"@/components/ui/field\"\n\nexport function FieldGroupExample() {\n return (\n \n
\n Responses\n \n Get notified when ChatGPT responds to requests that take time, like\n research or image generation.\n \n \n \n \n \n Push notifications\n \n \n \n
\n \n
\n Tasks\n \n Get notified when tasks you've created have updates.{\" \"}\n Manage tasks\n \n \n \n \n \n Push notifications\n \n \n \n \n \n Email notifications\n \n \n \n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-input.tsx", + "content": "import {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function FieldInput() {\n return (\n
\n \n \n Username\n \n \n Choose a unique username for your account.\n \n \n \n Password\n \n Must be at least 8 characters long.\n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-radio.tsx", + "content": "import {\n Field,\n FieldDescription,\n FieldLabel,\n FieldLegend,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n\nexport function FieldRadio() {\n return (\n
\n Subscription Plan\n \n Yearly and lifetime plans offer significant savings.\n \n \n \n \n \n Monthly ($9.99/month)\n \n \n \n \n \n Yearly ($99.99/year)\n \n \n \n \n \n Lifetime ($299.99)\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-responsive.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function FieldResponsive() {\n return (\n
\n
\n
\n Profile\n Fill in your profile information.\n \n \n \n Name\n \n Provide your full name for identification\n \n \n \n \n \n \n \n \n \n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\nimport { Textarea } from \"@/components/ui/textarea\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst months = [\n { label: \"MM\", value: null },\n { label: \"01\", value: \"01\" },\n { label: \"02\", value: \"02\" },\n { label: \"03\", value: \"03\" },\n { label: \"04\", value: \"04\" },\n { label: \"05\", value: \"05\" },\n { label: \"06\", value: \"06\" },\n { label: \"07\", value: \"07\" },\n { label: \"08\", value: \"08\" },\n { label: \"09\", value: \"09\" },\n { label: \"10\", value: \"10\" },\n { label: \"11\", value: \"11\" },\n { label: \"12\", value: \"12\" },\n]\n\nconst years = [\n { label: \"YYYY\", value: null },\n { label: \"2024\", value: \"2024\" },\n { label: \"2025\", value: \"2025\" },\n { label: \"2026\", value: \"2026\" },\n { label: \"2027\", value: \"2027\" },\n { label: \"2028\", value: \"2028\" },\n { label: \"2029\", value: \"2029\" },\n]\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n paymentMethod: \"Payment Method\",\n secureTransactions: \"All transactions are secure and encrypted\",\n nameOnCard: \"Name on Card\",\n cardNumber: \"Card Number\",\n cardNumberDescription: \"Enter your 16-digit card number\",\n month: \"Month\",\n year: \"Year\",\n cvv: \"CVV\",\n monthPlaceholder: \"MM\",\n month01: \"01\",\n month02: \"02\",\n month03: \"03\",\n month04: \"04\",\n month05: \"05\",\n month06: \"06\",\n month07: \"07\",\n month08: \"08\",\n month09: \"09\",\n month10: \"10\",\n month11: \"11\",\n month12: \"12\",\n billingAddress: \"Billing Address\",\n billingAddressDescription:\n \"The billing address associated with your payment method\",\n sameAsShipping: \"Same as shipping address\",\n comments: \"Comments\",\n commentsPlaceholder: \"Add any additional comments\",\n submit: \"Submit\",\n cancel: \"Cancel\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n paymentMethod: \"طريقة الدفع\",\n secureTransactions: \"جميع المعاملات آمنة ومشفرة\",\n nameOnCard: \"الاسم على البطاقة\",\n cardNumber: \"رقم البطاقة\",\n cardNumberDescription: \"أدخل رقم البطاقة المكون من 16 رقمًا\",\n month: \"الشهر\",\n year: \"السنة\",\n cvv: \"CVV\",\n monthPlaceholder: \"ش.ش\",\n month01: \"٠١\",\n month02: \"٠٢\",\n month03: \"٠٣\",\n month04: \"٠٤\",\n month05: \"٠٥\",\n month06: \"٠٦\",\n month07: \"٠٧\",\n month08: \"٠٨\",\n month09: \"٠٩\",\n month10: \"١٠\",\n month11: \"١١\",\n month12: \"١٢\",\n billingAddress: \"عنوان الفوترة\",\n billingAddressDescription: \"عنوان الفوترة المرتبط بطريقة الدفع الخاصة بك\",\n sameAsShipping: \"نفس عنوان الشحن\",\n comments: \"تعليقات\",\n commentsPlaceholder: \"أضف أي تعليقات إضافية\",\n submit: \"إرسال\",\n cancel: \"إلغاء\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n paymentMethod: \"אמצעי תשלום\",\n secureTransactions: \"כל העסקאות מאובטחות ומוצפנות\",\n nameOnCard: \"שם על הכרטיס\",\n cardNumber: \"מספר כרטיס\",\n cardNumberDescription: \"הזן את מספר הכרטיס בן 16 הספרות שלך\",\n month: \"חודש\",\n year: \"שנה\",\n cvv: \"CVV\",\n monthPlaceholder: \"MM\",\n month01: \"01\",\n month02: \"02\",\n month03: \"03\",\n month04: \"04\",\n month05: \"05\",\n month06: \"06\",\n month07: \"07\",\n month08: \"08\",\n month09: \"09\",\n month10: \"10\",\n month11: \"11\",\n month12: \"12\",\n billingAddress: \"כתובת חיוב\",\n billingAddressDescription: \"כתובת החיוב המשויכת לאמצעי התשלום שלך\",\n sameAsShipping: \"זהה לכתובת המשלוח\",\n comments: \"הערות\",\n commentsPlaceholder: \"הוסף הערות נוספות\",\n submit: \"שלח\",\n cancel: \"בטל\",\n },\n },\n}\n\nexport function FieldRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n const getMonthLabel = (value: string | null): string => {\n if (value === null) return t.monthPlaceholder\n const monthKey = `month${value}` as keyof typeof t\n return t[monthKey] || value\n }\n\n return (\n
\n
\n \n
\n {t.paymentMethod}\n {t.secureTransactions}\n \n \n \n {t.nameOnCard}\n \n \n \n \n \n {t.cardNumber}\n \n \n {t.cardNumberDescription}\n \n
\n \n \n {t.month}\n \n \n \n \n \n {t.year}\n \n \n \n \n \n {t.cvv}\n \n \n \n
\n
\n
\n \n
\n {t.billingAddress}\n {t.billingAddressDescription}\n \n \n \n \n {t.sameAsShipping}\n \n \n \n
\n
\n \n \n \n {t.comments}\n \n \n \n \n
\n \n \n \n \n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-select.tsx", + "content": "import { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nconst items = [\n { label: \"Choose department\", value: null },\n { label: \"Engineering\", value: \"engineering\" },\n { label: \"Design\", value: \"design\" },\n { label: \"Marketing\", value: \"marketing\" },\n { label: \"Sales\", value: \"sales\" },\n { label: \"Customer Support\", value: \"support\" },\n { label: \"Human Resources\", value: \"hr\" },\n { label: \"Finance\", value: \"finance\" },\n { label: \"Operations\", value: \"operations\" },\n]\n\nexport function FieldSelect() {\n return (\n \n Department\n \n \n Select your department or area of work.\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-slider.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Field, FieldDescription, FieldTitle } from \"@/components/ui/field\"\nimport { Slider } from \"@/components/ui/slider\"\n\nexport function FieldSlider() {\n const [value, setValue] = React.useState([200, 800])\n\n return (\n \n Price Range\n \n Set your budget range ($\n {value[0]} -{\" \"}\n {value[1]}).\n \n setValue(value as [number, number])}\n max={1000}\n min={0}\n step={10}\n className=\"mt-2 w-full\"\n aria-label=\"Price Range\"\n />\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-switch.tsx", + "content": "import { Field, FieldLabel } from \"@/components/ui/field\"\nimport { Switch } from \"@/components/ui/switch\"\n\nexport function FieldSwitch() {\n return (\n \n Multi-factor authentication\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-textarea.tsx", + "content": "import {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { Textarea } from \"@/components/ui/textarea\"\n\nexport function FieldTextarea() {\n return (\n
\n \n \n Feedback\n \n \n Share your thoughts about our service.\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/field/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/field.json b/public/r/react/styles/base-luma/field.json new file mode 100644 index 000000000..cfeebf0b6 --- /dev/null +++ b/public/r/react/styles/base-luma/field.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "field", + "title": "Field", + "description": "Combine labels, controls, and help text to compose accessible form fields and grouped inputs.", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/label", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/ui/field.tsx", + "content": "\"use client\"\n\nimport { useMemo } from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nimport { Label } from \"@/components/ui/label\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<\"fieldset\">) {\n return (\n [data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3 flex flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = \"legend\",\n ...props\n}: React.ComponentProps<\"legend\"> & { variant?: \"legend\" | \"label\" }) {\n return (\n \n )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nconst fieldVariants = cva(\"data-[invalid=true]:text-destructive gap-3 group/field flex w-full\", {\n variants: {\n orientation: {\n vertical: \"flex-col *:w-full [&>.sr-only]:w-auto\",\n horizontal:\n \"flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n responsive:\n \"flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n },\n },\n defaultVariants: {\n orientation: \"vertical\",\n },\n})\n\nfunction Field({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps) {\n return (\n \n )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction FieldLabel({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n [data-slot=field]]:rounded-2xl has-[>[data-slot=field]]:border has-[>[data-slot=field]]:not-has-[:disabled,[data-disabled]]:hover:bg-input/40 has-[>[data-slot=field]]:has-[:focus-visible]:border-ring has-[>[data-slot=field]]:has-[:focus-visible]:ring-ring/50 has-[>[data-slot=field]]:has-[:focus-visible]:ring-3 *:data-[slot=field]:p-4 group/field-label peer/field-label flex w-fit\",\n \"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction FieldDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<\"div\"> & {\n children?: React.ReactNode\n}) {\n return (\n \n \n {children && (\n \n {children}\n \n )}\n
\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n ...props\n}: React.ComponentProps<\"div\"> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const content = useMemo(() => {\n if (children) {\n return children\n }\n\n if (!errors?.length) {\n return null\n }\n\n const uniqueErrors = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n\n if (uniqueErrors?.length == 1) {\n return uniqueErrors[0]?.message\n }\n\n return (\n
    \n {uniqueErrors.map(\n (error, index) =>\n error?.message &&
  • {error.message}
  • \n )}\n
\n )\n }, [children, errors])\n\n if (!content) {\n return null\n }\n\n return (\n \n {content}\n
\n )\n}\n\nexport {\n Field,\n FieldLabel,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldContent,\n FieldTitle,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/field/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/footer-1.json b/public/r/react/styles/base-luma/footer-1.json new file mode 100644 index 000000000..be55e35b9 --- /dev/null +++ b/public/r/react/styles/base-luma/footer-1.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "footer-1", + "title": "Footer 1", + "description": "Footer layouts for utility navigation, brand presence, and last-mile calls to action.", + "registryDependencies": [ + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/footer-1.tsx", + "content": "import * as React from \"react\"\n\nimport { Icon } from \"@/components/ui/icon\"\nimport { Logo, LogoText } from \"@/components/ui/logo\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction Footer1({\n brandName,\n brandHref,\n description,\n socials,\n columns,\n copyright,\n ...props\n}: React.ComponentProps<\"footer\"> & {\n brandName: string\n brandHref: string\n description: string\n socials: {\n label: string\n href: string\n icon?: string\n }[]\n columns: {\n title: string\n links: {\n label: string\n href: string\n }[]\n }[]\n copyright: string\n}) {\n return (\n
\n
\n \n
\n
\n \n {brandName}\n \n

\n {description}\n

\n {socials.length > 0 && (\n
\n {socials.map((social) => (\n \n \n \n ))}\n
\n )}\n
\n
\n {columns.map((column) => (\n
\n

{column.title}

\n
    \n {column.links.map((link) => (\n
  • \n \n {link.label}\n \n
  • \n ))}\n
\n
\n ))}\n
\n
\n \n

{copyright}

\n
\n
\n
\n )\n}\n\nexport { Footer1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/footer/", + "categories": [ + "footer" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/footer-2.json b/public/r/react/styles/base-luma/footer-2.json new file mode 100644 index 000000000..13a675ad2 --- /dev/null +++ b/public/r/react/styles/base-luma/footer-2.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "footer-2", + "title": "Footer 2", + "description": "Footer layouts for utility navigation, brand presence, and last-mile calls to action.", + "registryDependencies": [ + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/footer-2.tsx", + "content": "import * as React from \"react\"\n\nimport { Icon } from \"@/components/ui/icon\"\nimport { Logo, LogoText } from \"@/components/ui/logo\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction Footer2({\n brandName,\n brandHref,\n description,\n links,\n socials,\n copyright,\n navigationLabel,\n ...props\n}: React.ComponentProps<\"footer\"> & {\n brandName: string\n brandHref: string\n description: string\n links: {\n label: string\n href: string\n }[]\n socials: {\n label: string\n href: string\n icon?: string\n }[]\n copyright: string\n navigationLabel: string\n}) {\n return (\n
\n
\n \n \n {brandName}\n \n

\n {description}\n

\n \n {links.map((link) => (\n \n {link.label}\n \n ))}\n \n {socials.length > 0 && (\n
\n {socials.map((social) => (\n \n \n \n ))}\n
\n )}\n \n

{copyright}

\n
\n
\n
\n )\n}\n\nexport { Footer2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/footer/", + "categories": [ + "footer" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/footer-3.json b/public/r/react/styles/base-luma/footer-3.json new file mode 100644 index 000000000..ed11b6ea8 --- /dev/null +++ b/public/r/react/styles/base-luma/footer-3.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "footer-3", + "title": "Footer 3", + "description": "Footer layouts for utility navigation, brand presence, and last-mile calls to action.", + "registryDependencies": [ + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/footer-3.tsx", + "content": "import * as React from \"react\"\n\nimport { Icon } from \"@/components/ui/icon\"\nimport { Logo, LogoText } from \"@/components/ui/logo\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction Footer3({\n brandName,\n brandHref,\n description,\n socials,\n columns,\n copyright,\n bottomLinks,\n navigationLabel,\n ...props\n}: React.ComponentProps<\"footer\"> & {\n brandName: string\n brandHref: string\n description: string\n socials: {\n label: string\n href: string\n icon?: string\n }[]\n columns: {\n title: string\n links: {\n label: string\n href: string\n }[]\n }[]\n copyright: string\n bottomLinks: {\n label: string\n href: string\n }[]\n navigationLabel: string\n}) {\n return (\n
\n
\n \n
\n
\n \n {brandName}\n \n

\n {description}\n

\n {socials.length > 0 && (\n
\n {socials.map((social) => (\n \n \n \n ))}\n
\n )}\n
\n
\n {columns.map((column) => (\n
\n

{column.title}

\n
    \n {column.links.map((link) => (\n
  • \n \n {link.label}\n \n
  • \n ))}\n
\n
\n ))}\n
\n
\n \n
\n

{copyright}

\n \n {bottomLinks.map((link) => (\n \n {link.label}\n \n ))}\n \n
\n
\n
\n
\n )\n}\n\nexport { Footer3 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/footer/", + "categories": [ + "footer" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/form.json b/public/r/react/styles/base-luma/form.json new file mode 100644 index 000000000..593a2ab82 --- /dev/null +++ b/public/r/react/styles/base-luma/form.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "form", + "title": "Form", + "description": "A form wrapper with vertical spacing for the field components.", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/form.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nfunction Form({ className, ...props }: React.ComponentProps<\"form\">) {\n return (\n \n )\n}\n\nexport { Form }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/form/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/header-1.json b/public/r/react/styles/base-luma/header-1.json new file mode 100644 index 000000000..c41ce6d1f --- /dev/null +++ b/public/r/react/styles/base-luma/header-1.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "header-1", + "title": "Header 1", + "description": "Header layouts for brand, navigation, and high-level page actions.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/navigation-menu", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/blocks/header-1.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { XIcon } from \"lucide-react\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { Header, HeaderContainer, HeaderGroup } from \"@/components/ui/header\"\nimport { Icon } from \"@/components/ui/icon\"\nimport { Logo, LogoImage, LogoText } from \"@/components/ui/logo\"\nimport {\n NavigationMenu,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n} from \"@/components/ui/navigation-menu\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\"\n\nfunction Header1({\n className,\n logo,\n navigation,\n buttons,\n navigationLabel,\n menu,\n ...props\n}: React.ComponentProps<\"header\"> & {\n logo: {\n label: string\n href: string\n src?: string\n srcLight?: string\n srcDark?: string\n }\n navigation: {\n label: string\n href: string\n active?: boolean\n }[]\n buttons: {\n label: string\n href: string\n icon?: string\n target?: \"_self\" | \"_blank\"\n }[]\n navigationLabel: string\n menu: {\n label: string\n title: string\n description: string\n closeLabel: string\n }\n}) {\n return (\n
\n \n \n \n \n {logo.label}\n \n \n \n \n {navigation.map((item, index) => (\n \n \n {item.label}\n \n \n ))}\n \n \n \n \n \n }\n >\n \n \n \n \n {menu.title}\n {menu.description}\n \n
\n \n {buttons.length > 0 && (\n
\n {buttons.map(({ label, href, icon, target }, index) => (\n \n }\n className={buttonVariants({\n variant:\n index === buttons.length - 1 ? \"default\" : \"outline\",\n })}\n >\n {icon && }\n {label}\n \n ))}\n
\n )}\n
\n \n }\n >\n \n {menu.closeLabel}\n \n
\n
\n
\n
\n )\n}\n\nexport { Header1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/header/", + "categories": [ + "header" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/header-2.json b/public/r/react/styles/base-luma/header-2.json new file mode 100644 index 000000000..5406f1df5 --- /dev/null +++ b/public/r/react/styles/base-luma/header-2.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "header-2", + "title": "Header 2", + "description": "Header layouts for brand, navigation, and high-level page actions.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/navigation-menu", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/blocks/header-2.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { XIcon } from \"lucide-react\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { Header, HeaderContainer, HeaderGroup } from \"@/components/ui/header\"\nimport { Icon } from \"@/components/ui/icon\"\nimport { Logo, LogoImage, LogoText } from \"@/components/ui/logo\"\nimport {\n NavigationMenu,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n} from \"@/components/ui/navigation-menu\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\"\n\nfunction Header2({\n className,\n logo,\n navigation,\n buttons,\n navigationLabel,\n menu,\n ...props\n}: React.ComponentProps<\"header\"> & {\n logo: {\n label: string\n href: string\n src?: string\n srcLight?: string\n srcDark?: string\n }\n navigation: {\n label: string\n href: string\n active?: boolean\n }[]\n buttons: {\n label: string\n href: string\n icon?: string\n target?: \"_self\" | \"_blank\"\n }[]\n navigationLabel: string\n menu: {\n label: string\n title: string\n description: string\n closeLabel: string\n }\n}) {\n return (\n
\n \n \n \n \n {logo.label}\n \n \n \n
\n )\n}\n\nexport { Header2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/header/", + "categories": [ + "header" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/header-3.json b/public/r/react/styles/base-luma/header-3.json new file mode 100644 index 000000000..a79141ac2 --- /dev/null +++ b/public/r/react/styles/base-luma/header-3.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "header-3", + "title": "Header 3", + "description": "Header layouts for brand, navigation, and high-level page actions.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/navigation-menu", + "@fulldev/separator", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/blocks/header-3.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { XIcon } from \"lucide-react\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { Header, HeaderContainer, HeaderGroup } from \"@/components/ui/header\"\nimport { Icon } from \"@/components/ui/icon\"\nimport { Logo, LogoImage, LogoText } from \"@/components/ui/logo\"\nimport {\n NavigationMenu,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n} from \"@/components/ui/navigation-menu\"\nimport { Separator } from \"@/components/ui/separator\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\"\n\nfunction Header3({\n className,\n logo,\n navigation,\n buttons,\n navigationLabel,\n menu,\n ...props\n}: React.ComponentProps<\"header\"> & {\n logo: {\n label: string\n href: string\n src?: string\n srcLight?: string\n srcDark?: string\n }\n navigation: {\n label: string\n href: string\n active?: boolean\n }[]\n buttons: {\n label: string\n href: string\n icon?: string\n target?: \"_self\" | \"_blank\"\n }[]\n navigationLabel: string\n menu: {\n label: string\n title: string\n description: string\n closeLabel: string\n }\n}) {\n return (\n
\n \n \n \n \n {logo.label}\n \n \n \n \n \n }\n >\n \n \n \n \n {menu.title}\n {menu.description}\n \n
\n \n {buttons.length > 0 && }\n {buttons.length > 0 && (\n
\n {buttons.map(({ label, href, icon, target }, index) => (\n \n }\n className={buttonVariants({\n variant:\n index === buttons.length - 1 ? \"default\" : \"outline\",\n })}\n >\n {icon && }\n {label}\n \n ))}\n
\n )}\n
\n \n }\n >\n \n {menu.closeLabel}\n \n
\n
\n
\n
\n )\n}\n\nexport { Header3 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/header/", + "categories": [ + "header" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/header-4.json b/public/r/react/styles/base-luma/header-4.json new file mode 100644 index 000000000..c19ea4e48 --- /dev/null +++ b/public/r/react/styles/base-luma/header-4.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "header-4", + "title": "Header 4", + "description": "Header layouts for brand, navigation, and high-level page actions.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/navigation-menu", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/blocks/header-4.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { XIcon } from \"lucide-react\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { Header, HeaderContainer, HeaderGroup } from \"@/components/ui/header\"\nimport { Icon } from \"@/components/ui/icon\"\nimport { Logo, LogoImage, LogoText } from \"@/components/ui/logo\"\nimport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n} from \"@/components/ui/navigation-menu\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\"\n\nfunction Header4({\n className,\n logo,\n navigation,\n buttons,\n navigationLabel,\n menu,\n ...props\n}: React.ComponentProps<\"header\"> & {\n logo: {\n label: string\n href: string\n src?: string\n srcLight?: string\n srcDark?: string\n }\n navigation: {\n label: string\n href: string\n description?: string\n active?: boolean\n image?: {\n src: string\n srcSet?: string\n width?: number\n height?: number\n }\n links?: {\n label: string\n href: string\n description?: string\n icon?: string\n active?: boolean\n }[]\n }[]\n buttons: {\n label: string\n href: string\n icon?: string\n target?: \"_self\" | \"_blank\"\n }[]\n navigationLabel: string\n menu: {\n label: string\n title: string\n description: string\n closeLabel: string\n }\n}) {\n return (\n
\n \n \n \n \n {logo.label}\n \n \n \n
\n )\n}\n\nexport { Header4 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/header/", + "categories": [ + "header" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/header-5.json b/public/r/react/styles/base-luma/header-5.json new file mode 100644 index 000000000..105e9911f --- /dev/null +++ b/public/r/react/styles/base-luma/header-5.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "header-5", + "title": "Header 5", + "description": "Header layouts for brand, navigation, and high-level page actions.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/navigation-menu", + "@fulldev/separator", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/blocks/header-5.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { XIcon } from \"lucide-react\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { Header, HeaderContainer, HeaderGroup } from \"@/components/ui/header\"\nimport { Icon } from \"@/components/ui/icon\"\nimport { Logo, LogoImage, LogoText } from \"@/components/ui/logo\"\nimport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n} from \"@/components/ui/navigation-menu\"\nimport { Separator } from \"@/components/ui/separator\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\"\n\nfunction Header5({\n className,\n logo,\n navigation,\n buttons,\n navigationLabel,\n menu,\n ...props\n}: React.ComponentProps<\"header\"> & {\n logo: {\n label: string\n href: string\n src?: string\n srcLight?: string\n srcDark?: string\n }\n navigation: {\n label: string\n href: string\n description?: string\n active?: boolean\n image?: {\n src: string\n srcSet?: string\n width?: number\n height?: number\n }\n links?: {\n label: string\n href: string\n description?: string\n icon?: string\n active?: boolean\n }[]\n }[]\n buttons: {\n label: string\n href: string\n icon?: string\n target?: \"_self\" | \"_blank\"\n }[]\n navigationLabel: string\n menu: {\n label: string\n title: string\n description: string\n closeLabel: string\n }\n}) {\n return (\n \n \n \n \n \n {logo.label}\n \n \n \n \n \n }\n >\n \n \n \n \n {menu.title}\n {menu.description}\n \n
\n \n {buttons.length > 0 && }\n {buttons.length > 0 && (\n
\n {buttons.map(({ label, href, icon, target }, index) => (\n \n }\n className={buttonVariants({\n variant:\n index === buttons.length - 1 ? \"default\" : \"outline\",\n })}\n >\n {icon && }\n {label}\n \n ))}\n
\n )}\n
\n \n }\n >\n \n {menu.closeLabel}\n \n
\n
\n
\n \n \n \n \n {navigation.map((item, index) =>\n item.links?.length ? (\n \n {item.label}\n \n
\n \n {item.image && (\n \n )}\n \n {item.label}\n {item.description && (\n \n {item.description}\n \n )}\n \n \n
\n {item.links.map((link) => (\n \n {link.icon && (\n \n )}\n \n {link.label}\n {link.description && (\n \n {link.description}\n \n )}\n \n \n ))}\n
\n
\n
\n \n ) : (\n \n \n {item.label}\n \n \n )\n )}\n
\n \n
\n \n )\n}\n\nexport { Header5 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/header/", + "categories": [ + "header" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/header.json b/public/r/react/styles/base-luma/header.json new file mode 100644 index 000000000..983cef12c --- /dev/null +++ b/public/r/react/styles/base-luma/header.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "header", + "title": "Header", + "description": "A responsive site header with grouped content.", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/header.tsx", + "content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nconst headerVariants = cva(\n \"py-2.5 relative z-50 flex w-full items-center gap-4\",\n {\n variants: {\n variant: {\n default: \"\",\n floating:\n \"my-2 rounded-4xl bg-background shadow-md ring-1 ring-foreground/5 dark:ring-foreground/10 mx-auto w-[calc(100%-2*var(--gutter,--spacing(4)))] max-w-[calc(var(--container,var(--container-7xl))-2*var(--gutter,--spacing(4)))] overflow-hidden\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Header({\n className,\n variant = \"default\",\n ...props\n}: React.ComponentProps<\"header\"> & VariantProps) {\n return (\n \n )\n}\n\nfunction HeaderContainer({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction HeaderGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nexport { Header, HeaderContainer, HeaderGroup, headerVariants }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/header/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-1.json b/public/r/react/styles/base-luma/hero-1.json new file mode 100644 index 000000000..bf70fa126 --- /dev/null +++ b/public/r/react/styles/base-luma/hero-1.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-1", + "title": "Hero 1", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-1.tsx", + "content": "import * as React from \"react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n} from \"@/components/ui/section\"\n\nfunction Hero1({\n title,\n description,\n badge,\n buttons,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n badge?: {\n label: string\n href: string\n }\n buttons: {\n label: string\n href: string\n }[]\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n}) {\n return (\n
\n \n {badge && (\n } variant=\"secondary\">\n {badge.label}\n \n )}\n

\n {title}\n

\n \n {description}\n \n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n \n \n \n
\n )\n}\n\nexport { Hero1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-10.json b/public/r/react/styles/base-luma/hero-10.json new file mode 100644 index 000000000..90d6d1874 --- /dev/null +++ b/public/r/react/styles/base-luma/hero-10.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-10", + "title": "Hero 10", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-10.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarImage,\n} from \"@/components/ui/avatar\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Rating } from \"@/components/ui/rating\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero10({\n className,\n title,\n description,\n buttons,\n socialProof,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n socialProof: {\n avatars: {\n image?: string\n initials: string\n }[]\n rating: number\n ratingLabel: string\n text: string\n }\n image: {\n src: string\n srcSet?: string\n width?: number\n height?: number\n }\n}) {\n return (\n \n \n
\n

\n {title}\n

\n

\n {description}\n

\n
\n
\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n \n {socialProof.avatars.map((avatar) => (\n \n \n {avatar.initials}\n \n ))}\n \n
\n \n \n {socialProof.text}\n \n
\n
\n
\n
\n
\n \n
\n \n )\n}\n\nexport { Hero10 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-11.json b/public/r/react/styles/base-luma/hero-11.json new file mode 100644 index 000000000..00dcc4827 --- /dev/null +++ b/public/r/react/styles/base-luma/hero-11.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-11", + "title": "Hero 11", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-11.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarImage,\n} from \"@/components/ui/avatar\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Rating } from \"@/components/ui/rating\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero11({\n className,\n title,\n description,\n buttons,\n socialProof,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n socialProof: {\n avatars: {\n image?: string\n initials: string\n }[]\n rating: number\n ratingLabel: string\n text: string\n }\n image: {\n src: string\n srcSet?: string\n width?: number\n height?: number\n }\n}) {\n return (\n \n \n

\n {title}\n

\n

\n {description}\n

\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n \n {socialProof.avatars.map((avatar) => (\n \n \n {avatar.initials}\n \n ))}\n \n
\n \n \n {socialProof.text}\n \n
\n
\n
\n
\n \n
\n \n )\n}\n\nexport { Hero11 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-12.json b/public/r/react/styles/base-luma/hero-12.json new file mode 100644 index 000000000..6637b6b7a --- /dev/null +++ b/public/r/react/styles/base-luma/hero-12.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-12", + "title": "Hero 12", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-12.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero12({\n className,\n title,\n description,\n buttons,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n}) {\n return (\n
\n \n
\n

\n {title}\n

\n

\n {description}\n

\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n
\n \n \n \n
\n )\n}\n\nexport { Hero12 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-13.json b/public/r/react/styles/base-luma/hero-13.json new file mode 100644 index 000000000..9bc02a4c7 --- /dev/null +++ b/public/r/react/styles/base-luma/hero-13.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-13", + "title": "Hero 13", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-13.tsx", + "content": "import * as React from \"react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero13({\n title,\n description,\n buttons,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n}) {\n return (\n
\n \n
\n
\n

\n {title}\n

\n

\n {description}\n

\n
\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n \n
\n
\n )\n}\n\nexport { Hero13 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-2.json b/public/r/react/styles/base-luma/hero-2.json new file mode 100644 index 000000000..e668e0e5f --- /dev/null +++ b/public/r/react/styles/base-luma/hero-2.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-2", + "title": "Hero 2", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-2.tsx", + "content": "import * as React from \"react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarImage,\n} from \"@/components/ui/avatar\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Rating } from \"@/components/ui/rating\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n} from \"@/components/ui/section\"\n\nfunction Hero2({\n title,\n description,\n buttons,\n socialProof,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n socialProof: {\n avatars: {\n image?: string\n initials: string\n }[]\n rating: number\n ratingLabel: string\n text: string\n }\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n}) {\n return (\n
\n \n
\n \n {socialProof.avatars.map((avatar) => (\n \n \n {avatar.initials}\n \n ))}\n \n
\n \n \n {socialProof.text}\n \n
\n
\n

\n {title}\n

\n \n {description}\n \n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n \n \n \n
\n )\n}\n\nexport { Hero2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-3.json b/public/r/react/styles/base-luma/hero-3.json new file mode 100644 index 000000000..b9dfb22ad --- /dev/null +++ b/public/r/react/styles/base-luma/hero-3.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-3", + "title": "Hero 3", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-3.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero3({\n className,\n title,\n description,\n buttons,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n image: {\n src: string\n srcSet?: string\n width?: number\n height?: number\n }\n}) {\n return (\n \n \n

\n {title}\n

\n

\n {description}\n

\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n
\n \n
\n \n )\n}\n\nexport { Hero3 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-4.json b/public/r/react/styles/base-luma/hero-4.json new file mode 100644 index 000000000..96f15cdfd --- /dev/null +++ b/public/r/react/styles/base-luma/hero-4.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-4", + "title": "Hero 4", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-4.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero4({\n className,\n title,\n description,\n features,\n buttons,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n features: string[]\n buttons: {\n label: string\n href: string\n }[]\n image: {\n src: string\n srcSet?: string\n width?: number\n height?: number\n }\n}) {\n return (\n \n \n

\n {title}\n

\n

\n {description}\n

\n
    \n {features.map((feature) => (\n
  • \n \n {feature}\n
  • \n ))}\n
\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n
\n \n
\n \n )\n}\n\nexport { Hero4 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-5.json b/public/r/react/styles/base-luma/hero-5.json new file mode 100644 index 000000000..56161d12e --- /dev/null +++ b/public/r/react/styles/base-luma/hero-5.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-5", + "title": "Hero 5", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-5.tsx", + "content": "import * as React from \"react\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarImage,\n} from \"@/components/ui/avatar\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Rating } from \"@/components/ui/rating\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero5({\n title,\n description,\n features,\n buttons,\n socialProof,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n features: string[]\n buttons: {\n label: string\n href: string\n }[]\n socialProof: {\n avatars: {\n image?: string\n initials: string\n }[]\n rating: number\n ratingLabel: string\n text: string\n }\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n}) {\n return (\n
\n \n
\n
\n

\n {title}\n

\n

\n {description}\n

\n
\n
    \n {features.map((feature) => (\n
  • \n \n {feature}\n
  • \n ))}\n
\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n \n {socialProof.avatars.map((avatar) => (\n \n \n {avatar.initials}\n \n ))}\n \n
\n \n \n {socialProof.text}\n \n
\n
\n
\n \n
\n
\n )\n}\n\nexport { Hero5 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-6.json b/public/r/react/styles/base-luma/hero-6.json new file mode 100644 index 000000000..5b2418f95 --- /dev/null +++ b/public/r/react/styles/base-luma/hero-6.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-6", + "title": "Hero 6", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-6.tsx", + "content": "import * as React from \"react\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarImage,\n} from \"@/components/ui/avatar\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Rating } from \"@/components/ui/rating\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero6({\n title,\n description,\n features,\n buttons,\n socialProof,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n features: string[]\n buttons: {\n label: string\n href: string\n }[]\n socialProof: {\n avatars: {\n image?: string\n initials: string\n }[]\n rating: number\n ratingLabel: string\n text: string\n }\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n}) {\n return (\n
\n \n \n
\n
\n

\n {title}\n

\n

\n {description}\n

\n
\n
    \n {features.map((feature) => (\n
  • \n \n {feature}\n
  • \n ))}\n
\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n \n {socialProof.avatars.map((avatar) => (\n \n \n {avatar.initials}\n \n ))}\n \n
\n \n \n {socialProof.text}\n \n
\n
\n
\n
\n
\n )\n}\n\nexport { Hero6 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-7.json b/public/r/react/styles/base-luma/hero-7.json new file mode 100644 index 000000000..2d4bf6968 --- /dev/null +++ b/public/r/react/styles/base-luma/hero-7.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-7", + "title": "Hero 7", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-7.tsx", + "content": "import * as React from \"react\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarImage,\n} from \"@/components/ui/avatar\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Rating } from \"@/components/ui/rating\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero7({\n title,\n description,\n features,\n buttons,\n socialProof,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n features: string[]\n buttons: {\n label: string\n href: string\n }[]\n socialProof: {\n avatars: {\n image?: string\n initials: string\n }[]\n rating: number\n ratingLabel: string\n text: string\n }\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n}) {\n return (\n
\n \n
\n
\n

\n {title}\n

\n

\n {description}\n

\n
\n
    \n {features.map((feature) => (\n
  • \n \n {feature}\n
  • \n ))}\n
\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n \n {socialProof.avatars.map((avatar) => (\n \n \n {avatar.initials}\n \n ))}\n \n
\n \n \n {socialProof.text}\n \n
\n
\n
\n \n
\n
\n )\n}\n\nexport { Hero7 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-8.json b/public/r/react/styles/base-luma/hero-8.json new file mode 100644 index 000000000..129c1fcd1 --- /dev/null +++ b/public/r/react/styles/base-luma/hero-8.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-8", + "title": "Hero 8", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-8.tsx", + "content": "import * as React from \"react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero8({\n title,\n description,\n buttons,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n}) {\n return (\n
\n \n
\n
\n

\n {title}\n

\n

\n {description}\n

\n
\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n \n
\n
\n )\n}\n\nexport { Hero8 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hero-9.json b/public/r/react/styles/base-luma/hero-9.json new file mode 100644 index 000000000..5e5766538 --- /dev/null +++ b/public/r/react/styles/base-luma/hero-9.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hero-9", + "title": "Hero 9", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-9.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarGroup,\n AvatarImage,\n} from \"@/components/ui/avatar\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Rating } from \"@/components/ui/rating\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Hero9({\n className,\n title,\n description,\n features,\n buttons,\n socialProof,\n image,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n features: string[]\n buttons: {\n label: string\n href: string\n }[]\n socialProof: {\n avatars: {\n image?: string\n initials: string\n }[]\n rating: number\n ratingLabel: string\n text: string\n }\n image: {\n src: string\n srcSet?: string\n width?: number\n height?: number\n }\n}) {\n return (\n \n \n
\n
\n

\n {title}\n

\n

\n {description}\n

\n
\n
    \n {features.map((feature) => (\n
  • \n \n {feature}\n
  • \n ))}\n
\n
\n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
\n
\n \n {socialProof.avatars.map((avatar) => (\n \n \n {avatar.initials}\n \n ))}\n \n
\n \n \n {socialProof.text}\n \n
\n
\n
\n
\n
\n \n
\n \n )\n}\n\nexport { Hero9 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "categories": [ + "hero" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hover-card-examples.json b/public/r/react/styles/base-luma/hover-card-examples.json new file mode 100644 index 000000000..755c9d07e --- /dev/null +++ b/public/r/react/styles/base-luma/hover-card-examples.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hover-card-examples", + "title": "Hover Card examples", + "description": "The examples from the shadcn/ui Hover Card docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/hover-card", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/hover-card/hover-card-demo.tsx", + "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n HoverCard,\n HoverCardContent,\n HoverCardTrigger,\n} from \"@/components/ui/hover-card\"\n\nexport function HoverCardDemo() {\n return (\n \n }\n >\n Hover Here\n \n \n
@nextjs
\n
The React Framework – created and maintained by @vercel.
\n
\n Joined December 2021\n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/hover-card/hover-card-rtl.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n HoverCard,\n HoverCardContent,\n HoverCardTrigger,\n} from \"@/components/ui/hover-card\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n trigger: \"Wireless Headphones\",\n name: \"Wireless Headphones\",\n price: \"$99.99\",\n \"inline-start\": \"Inline Start\",\n left: \"Left\",\n top: \"Top\",\n bottom: \"Bottom\",\n right: \"Right\",\n \"inline-end\": \"Inline End\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n trigger: \"سماعات لاسلكية\",\n name: \"سماعات لاسلكية\",\n price: \"٩٩.٩٩ $\",\n \"inline-start\": \"بداية السطر\",\n left: \"يسار\",\n top: \"أعلى\",\n bottom: \"أسفل\",\n right: \"يمين\",\n \"inline-end\": \"نهاية السطر\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n trigger: \"אוזניות אלחוטיות\",\n name: \"אוזניות אלחוטיות\",\n price: \"99.99 $\",\n \"inline-start\": \"תחילת השורה\",\n left: \"שמאל\",\n top: \"למעלה\",\n bottom: \"למטה\",\n right: \"ימין\",\n \"inline-end\": \"סוף השורה\",\n },\n },\n}\n\nconst physicalSides = [\"left\", \"top\", \"bottom\", \"right\"] as const\nconst logicalSides = [\"inline-start\", \"inline-end\"] as const\n\nexport function HoverCardRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n
\n
\n {physicalSides.map((side) => (\n \n }\n >\n {t[side]}\n \n \n
{t.name}
\n
{t.price}
\n \n
\n ))}\n
\n
\n {logicalSides.map((side) => (\n \n }\n >\n {t[side]}\n \n \n
{t.name}
\n
{t.price}
\n \n
\n ))}\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/hover-card/hover-card-sides.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n HoverCard,\n HoverCardContent,\n HoverCardTrigger,\n} from \"@/components/ui/hover-card\"\n\nconst HOVER_CARD_SIDES = [\"left\", \"top\", \"bottom\", \"right\"] as const\n\nexport function HoverCardSides() {\n return (\n
\n {HOVER_CARD_SIDES.map((side) => (\n \n }\n >\n {side}\n \n \n
\n

Hover Card

\n

This hover card appears on the {side} side of the trigger.

\n
\n
\n
\n ))}\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/hover-card/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/hover-card.json b/public/r/react/styles/base-luma/hover-card.json new file mode 100644 index 000000000..fc8b58237 --- /dev/null +++ b/public/r/react/styles/base-luma/hover-card.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "hover-card", + "title": "Hover Card", + "description": "For sighted users to preview content available behind a link.", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/hover-card.tsx", + "content": "\"use client\"\n\nimport { PreviewCard as PreviewCardPrimitive } from \"@base-ui/react/preview-card\"\nimport { cn } from \"cn\"\n\nfunction HoverCard({ ...props }: PreviewCardPrimitive.Root.Props) {\n return \n}\n\nfunction HoverCardTrigger({ ...props }: PreviewCardPrimitive.Trigger.Props) {\n return (\n \n )\n}\n\nfunction HoverCardContent({\n className,\n side = \"bottom\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 4,\n ...props\n}: PreviewCardPrimitive.Popup.Props &\n Pick<\n PreviewCardPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n \n \n \n \n \n )\n}\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/hover-card/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/icon.json b/public/r/react/styles/base-luma/icon.json new file mode 100644 index 000000000..ec38ed3d4 --- /dev/null +++ b/public/r/react/styles/base-luma/icon.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "icon", + "title": "Icon", + "description": "Renders a Lucide icon or a social brand logo by name, or the icon for a link.", + "dependencies": [ + "cn", + "lucide-react", + "simple-icons" + ], + "files": [ + { + "path": "src/components/ui/icon.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport * as lucide from \"lucide-react\"\nimport * as simpleIcons from \"simple-icons\"\nimport type { SimpleIcon } from \"simple-icons\"\n\n// Names come from content, so every Lucide icon and every Simple Icons brand\n// can be rendered. For an icon fixed in code, import it from lucide-react or\n// simple-icons directly instead.\n\n// The icon for a link, by a part of its href.\nconst hrefIcons = {\n \"x.com\": \"x\",\n twitter: \"twitter\",\n facebook: \"facebook\",\n instagram: \"instagram\",\n pinterest: \"pinterest\",\n youtube: \"youtube\",\n tiktok: \"tiktok\",\n snapchat: \"snapchat\",\n reddit: \"reddit\",\n tumblr: \"tumblr\",\n \"wa.me\": \"whatsapp\",\n telegram: \"telegram\",\n discord: \"discord\",\n vimeo: \"vimeo\",\n flickr: \"flickr\",\n yelp: \"yelp\",\n spotify: \"spotify\",\n behance: \"behance\",\n dribbble: \"dribbble\",\n soundcloud: \"soundcloud\",\n github: \"github\",\n twitch: \"twitch\",\n \"tel:\": \"phone\",\n \"mailto:\": \"mail\",\n \"maps.app.goo.gl\": \"map-pin\",\n linkedin: \"linkedin\",\n} as const\n\ntype Source = \"lucide\" | \"simple\"\ntype Resolved =\n | { source: \"lucide\"; icon: lucide.LucideIcon }\n | { source: \"simple\"; icon: SimpleIcon }\n\n// `map-pin` is the `MapPin` export of lucide-react, aliases included.\nfunction lucideIcon(name: string) {\n const key = name\n .split(\"-\")\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\"\")\n const icon = (lucide as Record)[key]\n if (typeof icon !== \"object\" || icon === null || !(\"$$typeof\" in icon)) return\n return icon as lucide.LucideIcon\n}\n\n// `github` is the `siGithub` export of simple-icons.\nfunction simpleIcon(slug: string) {\n const icon = (simpleIcons as Record)[\n `si${slug.charAt(0).toUpperCase()}${slug.slice(1)}`\n ]\n if (typeof icon !== \"object\" || icon === null || !(\"path\" in icon)) return\n return icon as SimpleIcon\n}\n\nfunction find(source: Source, name: string): Resolved | undefined {\n if (source === \"simple\") {\n const icon = simpleIcon(name)\n return icon && { source, icon }\n }\n const icon = lucideIcon(name)\n return icon && { source, icon }\n}\n\n// Resolve an icon by name, or derive one from a link href. Names may start\n// with `lucide:` or `simple:` to pick a set when both have the name.\nfunction resolveIcon(name?: string | number, href?: string) {\n const named = name != null && name !== \"\"\n let key = named ? String(name) : undefined\n let order: Source[] = [\"lucide\", \"simple\"]\n\n if (!key && href) {\n const match = Object.keys(hrefIcons).find((part) => href.includes(part))\n if (match) {\n key = hrefIcons[match as keyof typeof hrefIcons]\n order = [\"simple\", \"lucide\"]\n }\n }\n\n const link = find(\"lucide\", \"link\")\n if (!key) return href ? link : undefined\n if (key === \"x.com\") key = \"simple:x\"\n\n const [prefix, icon] = key.includes(\":\") ? key.split(\":\") : [undefined, key]\n if (prefix === \"lucide\" || prefix === \"simple\") order = [prefix]\n\n for (const source of order) {\n const resolved = find(source, icon)\n if (resolved) return resolved\n }\n // A link always gets an icon, even when its brand has no logo.\n return named ? undefined : link\n}\n\nfunction Icon({\n className,\n name,\n href,\n ...props\n}: Omit, \"name\"> & {\n name?: string | number\n href?: string\n}) {\n const resolved = resolveIcon(name, href)\n if (!resolved) return null\n const labelled =\n \"aria-label\" in props || \"aria-labelledby\" in props || \"role\" in props\n const shared = {\n \"data-slot\": \"icon\",\n width: 24,\n height: 24,\n \"aria-hidden\": labelled ? undefined : true,\n className: cn(\"size-[1em] text-base\", className),\n }\n\n if (resolved.source === \"lucide\") {\n const LucideIcon = resolved.icon\n return \n }\n return (\n \n \n \n )\n}\n\nexport { Icon }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/icon/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/init.json b/public/r/react/styles/base-luma/init.json new file mode 100644 index 000000000..84aa33b89 --- /dev/null +++ b/public/r/react/styles/base-luma/init.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "init", + "title": "Init", + "description": "Class helper, dependencies, and base styles for an existing project. Leaves theme tokens alone.", + "dependencies": [ + "class-variance-authority", + "cn", + "shadcn", + "tw-animate-css" + ], + "files": [ + { + "path": "src/lib/utils.ts", + "content": "export { cn } from \"cn\"\n", + "type": "registry:lib" + } + ], + "css": { + "@import \"tw-animate-css\"": {}, + "@import \"shadcn/tailwind.css\"": {}, + "@layer base": { + "*": { + "@apply border-border outline-ring/50": {} + }, + "html": { + "@apply font-sans": {} + }, + "body": { + "@apply bg-background text-foreground": {} + } + }, + "@media (prefers-reduced-motion: reduce)": { + "*, ::before, ::after": { + "animation-duration": "0.01ms !important", + "animation-iteration-count": "1 !important", + "transition-duration": "0.01ms !important", + "scroll-behavior": "auto !important" + } + } + }, + "docs": "https://ui.full.dev/react/docs/installation/", + "type": "registry:lib" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/input-examples.json b/public/r/react/styles/base-luma/input-examples.json new file mode 100644 index 000000000..be97e8420 --- /dev/null +++ b/public/r/react/styles/base-luma/input-examples.json @@ -0,0 +1,103 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "input-examples", + "title": "Input examples", + "description": "The examples from the shadcn/ui Input docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/button-group", + "@fulldev/field", + "@fulldev/input", + "@fulldev/input-group", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/input/input-badge.tsx", + "content": "import { Badge } from \"@/components/ui/badge\"\nimport { Field, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputBadge() {\n return (\n \n \n Webhook URL{\" \"}\n \n Beta\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-basic.tsx", + "content": "import { Input } from \"@/components/ui/input\"\n\nexport function InputBasic() {\n return \n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-button-group.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport { Field, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputButtonGroup() {\n return (\n \n Search\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-demo.tsx", + "content": "import { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputDemo() {\n return (\n \n API Key\n \n \n Your API key is encrypted and stored securely.\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-disabled.tsx", + "content": "import { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputDisabled() {\n return (\n \n Email\n \n This field is currently disabled.\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-field.tsx", + "content": "import { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputField() {\n return (\n \n Username\n \n \n Choose a unique username for your account.\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-fieldgroup.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputFieldgroup() {\n return (\n \n \n Name\n \n \n \n Email\n \n \n We'll send updates to this address.\n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-file.tsx", + "content": "import { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputFile() {\n return (\n \n Picture\n \n Select a picture to upload.\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-form.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport function InputForm() {\n const countries = [\n { label: \"United States\", value: \"us\" },\n { label: \"United Kingdom\", value: \"uk\" },\n { label: \"Canada\", value: \"ca\" },\n ]\n return (\n
\n \n \n Name\n \n \n \n Email\n \n \n We'll never share your email with anyone.\n \n \n
\n \n Phone\n \n \n \n Country\n \n \n
\n \n Address\n \n \n \n \n \n \n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-grid.tsx", + "content": "import { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputGrid() {\n return (\n \n \n First Name\n \n \n \n Last Name\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-inline.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport { Field } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputInline() {\n return (\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-input-group.tsx", + "content": "import { InfoIcon } from \"lucide-react\"\n\nimport { Field, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n InputGroupText,\n} from \"@/components/ui/input-group\"\n\nexport function InputInputGroup() {\n return (\n \n Website URL\n \n \n \n https://\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-invalid.tsx", + "content": "import { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputInvalid() {\n return (\n \n Invalid Input\n \n \n This field contains validation errors.\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-required.tsx", + "content": "import { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\n\nexport function InputRequired() {\n return (\n \n \n Required Field *\n \n \n This field must be filled out.\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n apiKey: \"API Key\",\n placeholder: \"sk-...\",\n description: \"Your API key is encrypted and stored securely.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n apiKey: \"مفتاح API\",\n placeholder: \"sk-...\",\n description: \"مفتاح API الخاص بك مشفر ومخزن بأمان.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n apiKey: \"מפתח API\",\n placeholder: \"sk-...\",\n description: \"מפתח ה-API שלך מוצפן ונשמר בצורה מאובטחת.\",\n },\n },\n}\n\nexport function InputRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n \n {t.apiKey}\n \n {t.description}\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/input/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/input-group-examples.json b/public/r/react/styles/base-luma/input-group-examples.json new file mode 100644 index 000000000..6d8778727 --- /dev/null +++ b/public/r/react/styles/base-luma/input-group-examples.json @@ -0,0 +1,105 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "input-group-examples", + "title": "Input Group examples", + "description": "The examples from the shadcn/ui Input Group docs.", + "dependencies": [ + "@tabler/icons-react", + "cn", + "lucide-react", + "react-textarea-autosize" + ], + "registryDependencies": [ + "@fulldev/dropdown-menu", + "@fulldev/field", + "@fulldev/input-group", + "@fulldev/kbd", + "@fulldev/popover", + "@fulldev/select", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/input-group/input-group-block-end.tsx", + "content": "import {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n InputGroupText,\n InputGroupTextarea,\n} from \"@/components/ui/input-group\"\n\nexport function InputGroupBlockEnd() {\n return (\n \n \n Input\n \n \n \n USD\n \n \n Footer positioned below the input.\n \n \n Textarea\n \n \n \n 0/280\n \n Post\n \n \n \n \n Footer positioned below the textarea.\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-block-start.tsx", + "content": "import { CopyIcon, FileCodeIcon } from \"lucide-react\"\n\nimport {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n InputGroupText,\n InputGroupTextarea,\n} from \"@/components/ui/input-group\"\n\nexport function InputGroupBlockStart() {\n return (\n \n \n Input\n \n \n \n Full Name\n \n \n Header positioned above the input.\n \n \n Textarea\n \n \n \n \n script.js\n \n \n Copy\n \n \n \n \n Header positioned above the textarea.\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-button.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n IconCheck,\n IconCopy,\n IconInfoCircle,\n IconStar,\n} from \"@tabler/icons-react\"\n\nimport { useCopyToClipboard } from \"@/hooks/use-copy-to-clipboard\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n\nexport function InputGroupButtonExample() {\n const { copyToClipboard, isCopied } = useCopyToClipboard()\n const [isFavorite, setIsFavorite] = React.useState(false)\n\n return (\n
\n \n \n \n {\n copyToClipboard(\"https://x.com/shadcn\")\n }}\n >\n {isCopied ? : }\n \n \n \n \n \n }>\n \n \n \n \n \n

Your connection is not secure.

\n

You should not enter any sensitive information on this site.

\n \n
\n \n https://\n \n \n \n setIsFavorite(!isFavorite)}\n size=\"icon-xs\"\n >\n \n \n \n
\n \n \n \n Search\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-custom.tsx", + "content": "\"use client\"\n\nimport TextareaAutosize from \"react-textarea-autosize\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n} from \"@/components/ui/input-group\"\n\nexport function InputGroupCustom() {\n return (\n
\n \n \n \n \n Submit\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-demo.tsx", + "content": "import { Search } from \"lucide-react\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n\nexport function InputGroupDemo() {\n return (\n \n \n \n \n \n 12 results\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-dropdown.tsx", + "content": "\"use client\"\n\nimport { ChevronDownIcon, MoreHorizontal } from \"lucide-react\"\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n\nexport function InputGroupDropdown() {\n return (\n
\n \n \n \n \n \n }\n >\n \n \n \n \n Settings\n Copy path\n Open location\n \n \n \n \n \n \n \n \n \n \n }\n >\n Search In... \n \n \n \n Documentation\n Blog Posts\n Changelog\n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-icon.tsx", + "content": "import {\n CheckIcon,\n CreditCardIcon,\n InfoIcon,\n MailIcon,\n SearchIcon,\n StarIcon,\n} from \"lucide-react\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n\nexport function InputGroupIcon() {\n return (\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-inline-end.tsx", + "content": "import { EyeOffIcon } from \"lucide-react\"\n\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n\nexport function InputGroupInlineEnd() {\n return (\n \n Input\n \n \n \n \n \n \n Icon positioned at the end.\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-inline-start.tsx", + "content": "import { SearchIcon } from \"lucide-react\"\n\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\n\nexport function InputGroupInlineStart() {\n return (\n \n Input\n \n \n \n \n \n \n Icon positioned at the start.\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-kbd.tsx", + "content": "import { SearchIcon } from \"lucide-react\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport { Kbd } from \"@/components/ui/kbd\"\n\nexport function InputGroupKbd() {\n return (\n \n \n \n \n \n \n ⌘K\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Search } from \"lucide-react\"\n\nimport {\n Field,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n InputGroupText,\n InputGroupTextarea,\n} from \"@/components/ui/input-group\"\nimport { Spinner } from \"@/components/ui/spinner\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n placeholder: \"Search...\",\n results: \"12 results\",\n searching: \"Searching...\",\n saving: \"Saving...\",\n savingChanges: \"Saving changes...\",\n textareaLabel: \"Textarea\",\n textareaPlaceholder: \"Write a comment...\",\n characterCount: \"0/280\",\n post: \"Post\",\n textareaDescription: \"Footer positioned below the textarea.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n placeholder: \"بحث...\",\n results: \"١٢ نتيجة\",\n searching: \"جاري البحث...\",\n saving: \"جاري الحفظ...\",\n savingChanges: \"جاري حفظ التغييرات...\",\n textareaLabel: \"منطقة النص\",\n textareaPlaceholder: \"اكتب تعليقًا...\",\n characterCount: \"٠/٢٨٠\",\n post: \"نشر\",\n textareaDescription: \"تذييل موضع أسفل منطقة النص.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n placeholder: \"חפש...\",\n results: \"12 תוצאות\",\n searching: \"מחפש...\",\n saving: \"שומר...\",\n savingChanges: \"שומר שינויים...\",\n textareaLabel: \"אזור טקסט\",\n textareaPlaceholder: \"כתוב תגובה...\",\n characterCount: \"0/280\",\n post: \"פרסם\",\n textareaDescription: \"כותרת תחתונה ממוקמת מתחת לאזור הטקסט.\",\n },\n },\n}\n\nexport function InputGroupRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n
\n \n \n \n \n \n {t.results}\n \n \n \n \n \n \n \n \n \n \n {t.saving}\n \n \n \n \n \n {t.textareaLabel}\n \n \n \n {t.characterCount}\n \n {t.post}\n \n \n \n {t.textareaDescription}\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-spinner.tsx", + "content": "import { LoaderIcon } from \"lucide-react\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n InputGroupText,\n} from \"@/components/ui/input-group\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\nexport function InputGroupSpinner() {\n return (\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Saving...\n \n \n \n \n \n \n \n \n \n \n Please wait...\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-text.tsx", + "content": "import {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n InputGroupText,\n InputGroupTextarea,\n} from \"@/components/ui/input-group\"\n\nexport function InputGroupTextExample() {\n return (\n
\n \n \n $\n \n \n \n USD\n \n \n \n \n https://\n \n \n \n .com\n \n \n \n \n \n @company.com\n \n \n \n \n \n \n 120 characters left\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-textarea.tsx", + "content": "import {\n IconBrandJavascript,\n IconCopy,\n IconCornerDownLeft,\n IconRefresh,\n} from \"@tabler/icons-react\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupText,\n InputGroupTextarea,\n} from \"@/components/ui/input-group\"\n\nexport function InputGroupTextareaExample() {\n return (\n
\n \n \n \n Line 1, Column 1\n \n Run \n \n \n \n \n \n script.js\n \n \n \n \n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/hooks/use-copy-to-clipboard.ts", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nfunction legacyCopyToClipboard(value: string) {\n const textArea = document.createElement(\"textarea\")\n textArea.value = value\n textArea.setAttribute(\"readonly\", \"\")\n textArea.style.position = \"fixed\"\n textArea.style.opacity = \"0\"\n textArea.style.pointerEvents = \"none\"\n\n document.body.appendChild(textArea)\n textArea.focus()\n textArea.select()\n textArea.setSelectionRange(0, value.length)\n\n let hasCopied = false\n try {\n hasCopied = document.execCommand(\"copy\")\n } catch {\n hasCopied = false\n }\n\n document.body.removeChild(textArea)\n return hasCopied\n}\n\nexport function useCopyToClipboard({\n timeout = 2000,\n onCopy,\n}: {\n timeout?: number\n onCopy?: () => void\n} = {}) {\n const [isCopied, setIsCopied] = React.useState(false)\n\n const copyToClipboard = async (value: string) => {\n if (typeof window === \"undefined\") {\n return false\n }\n\n if (!value) {\n return false\n }\n\n let hasCopied = false\n\n if (navigator.clipboard?.writeText) {\n try {\n await navigator.clipboard.writeText(value)\n hasCopied = true\n } catch {\n hasCopied = legacyCopyToClipboard(value)\n }\n } else {\n hasCopied = legacyCopyToClipboard(value)\n }\n\n if (!hasCopied) {\n return false\n }\n\n setIsCopied(true)\n\n if (onCopy) {\n onCopy()\n }\n\n if (timeout !== 0) {\n setTimeout(() => {\n setIsCopied(false)\n }, timeout)\n }\n\n return true\n }\n\n return { isCopied, copyToClipboard }\n}\n", + "type": "registry:hook" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/input-group/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/input-group.json b/public/r/react/styles/base-luma/input-group.json new file mode 100644 index 000000000..490ff2a0a --- /dev/null +++ b/public/r/react/styles/base-luma/input-group.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "input-group", + "title": "Input Group", + "description": "Add addons, buttons, and helper content to inputs.", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/input", + "@fulldev/textarea" + ], + "files": [ + { + "path": "src/components/ui/input-group.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport { Textarea } from \"@/components/ui/textarea\"\n\nfunction InputGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n [data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5 relative flex w-full min-w-0 items-center outline-none has-[>textarea]:h-auto\",\n className\n )}\n {...props}\n />\n )\n}\n\nconst inputGroupAddonVariants = cva(\n \"text-muted-foreground **:data-[slot=kbd]:bg-muted-foreground/10 h-auto gap-2 py-2 text-sm font-medium group-data-[disabled=true]/input-group:opacity-50 **:data-[slot=kbd]:rounded-3xl **:data-[slot=kbd]:px-1.5 [&>svg:not([class*='size-'])]:size-4 flex cursor-text items-center justify-center select-none\",\n {\n variants: {\n align: {\n \"inline-start\": \"pl-3 has-[>button]:-ml-1 has-[>kbd]:-ml-1 order-first\",\n \"inline-end\": \"pr-3 has-[>button]:-mr-1 has-[>kbd]:-mr-1 order-last\",\n \"block-start\":\n \"px-3 pt-3 group-has-[>input]/input-group:pt-3.5 [.border-b]:pb-3.5 order-first w-full justify-start\",\n \"block-end\":\n \"px-3 pb-3 group-has-[>input]/input-group:pb-3.5 [.border-t]:pt-3.5 order-last w-full justify-start\",\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n }\n)\n\nfunction InputGroupAddon({\n className,\n align = \"inline-start\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps) {\n return (\n {\n if ((e.target as HTMLElement).closest(\"button\")) {\n return\n }\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus()\n }}\n {...props}\n />\n )\n}\n\nconst inputGroupButtonVariants = cva(\n \"gap-2 rounded-4xl text-sm flex items-center shadow-none\",\n {\n variants: {\n size: {\n xs: \"h-6 gap-1 rounded-xl px-1.5 [&>svg:not([class*='size-'])]:size-3.5\",\n sm: \"\",\n \"icon-xs\": \"size-6 rounded-xl p-0 has-[>svg]:p-0\",\n \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\n },\n },\n defaultVariants: {\n size: \"xs\",\n },\n }\n)\n\nfunction InputGroupButton({\n className,\n type = \"button\",\n variant = \"ghost\",\n size = \"xs\",\n ...props\n}: Omit, \"size\" | \"type\"> &\n VariantProps & {\n type?: \"button\" | \"submit\" | \"reset\"\n }) {\n return (\n \n )\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n \n )\n}\n\nfunction InputGroupInput({\n className,\n ...props\n}: React.ComponentProps<\"input\">) {\n return (\n \n )\n}\n\nfunction InputGroupTextarea({\n className,\n ...props\n}: React.ComponentProps<\"textarea\">) {\n return (\n \n )\n}\n\nexport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupText,\n InputGroupInput,\n InputGroupTextarea,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/input-group/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/input-otp-examples.json b/public/r/react/styles/base-luma/input-otp-examples.json new file mode 100644 index 000000000..e53bb7e24 --- /dev/null +++ b/public/r/react/styles/base-luma/input-otp-examples.json @@ -0,0 +1,77 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "input-otp-examples", + "title": "Input Otp examples", + "description": "The examples from the shadcn/ui Input Otp docs.", + "dependencies": [ + "cn", + "input-otp", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/field", + "@fulldev/input-otp", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/input-otp/input-otp-alphanumeric.tsx", + "content": "\"use client\"\n\nimport { REGEXP_ONLY_DIGITS_AND_CHARS } from \"input-otp\"\n\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSeparator,\n InputOTPSlot,\n} from \"@/components/ui/input-otp\"\n\nexport function InputOTPAlphanumeric() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-controlled.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n} from \"@/components/ui/input-otp\"\n\nexport function InputOTPControlled() {\n const [value, setValue] = React.useState(\"\")\n\n return (\n
\n setValue(value)}\n >\n \n \n \n \n \n \n \n \n \n
\n {value === \"\" ? (\n <>Enter your one-time password.\n ) : (\n <>You entered: {value}\n )}\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-demo.tsx", + "content": "import {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n} from \"@/components/ui/input-otp\"\n\nexport function InputOTPDemo() {\n return (\n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-disabled.tsx", + "content": "import { Field, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSeparator,\n InputOTPSlot,\n} from \"@/components/ui/input-otp\"\n\nexport function InputOTPDisabled() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-form.tsx", + "content": "import { RefreshCwIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSeparator,\n InputOTPSlot,\n} from \"@/components/ui/input-otp\"\n\nexport function InputOTPForm() {\n return (\n \n \n Verify your login\n \n Enter the verification code we sent to your email address:{\" \"}\n m@example.com.\n \n \n \n \n
\n \n Verification code\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n I no longer have access to this email address.\n \n
\n
\n \n \n \n
\n Having trouble signing in?{\" \"}\n \n Contact support\n \n
\n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-four-digits.tsx", + "content": "\"use client\"\n\nimport { REGEXP_ONLY_DIGITS } from \"input-otp\"\n\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n} from \"@/components/ui/input-otp\"\n\nexport function InputOTPFourDigits() {\n return (\n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-invalid.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSeparator,\n InputOTPSlot,\n} from \"@/components/ui/input-otp\"\n\nexport function InputOTPInvalid() {\n const [value, setValue] = React.useState(\"000000\")\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-pattern.tsx", + "content": "\"use client\"\n\nimport { REGEXP_ONLY_DIGITS } from \"input-otp\"\n\nimport { Field, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n} from \"@/components/ui/input-otp\"\n\nexport function InputOTPPattern() {\n return (\n \n Digits Only\n \n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Field, FieldLabel } from \"@/components/ui/field\"\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n} from \"@/components/ui/input-otp\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n verificationCode: \"Verification code\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n verificationCode: \"رمز التحقق\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n verificationCode: \"קוד אימות\",\n },\n },\n}\n\nexport function InputOTPRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n \n {t.verificationCode}\n \n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-separator.tsx", + "content": "import {\n InputOTP,\n InputOTPGroup,\n InputOTPSeparator,\n InputOTPSlot,\n} from \"@/components/ui/input-otp\"\n\nexport function InputOTPWithSeparator() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/input-otp/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/input-otp.json b/public/r/react/styles/base-luma/input-otp.json new file mode 100644 index 000000000..41af78026 --- /dev/null +++ b/public/r/react/styles/base-luma/input-otp.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "input-otp", + "title": "Input OTP", + "description": "An accessible one-time password input with copy and paste support.", + "dependencies": [ + "cn", + "input-otp", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/input-otp.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\nimport { OTPInput, OTPInputContext } from \"input-otp\"\nimport { MinusIcon } from \"lucide-react\"\n\nfunction InputOTP({\n className,\n containerClassName,\n ...props\n}: React.ComponentProps & {\n containerClassName?: string\n}) {\n return (\n \n )\n}\n\nfunction InputOTPGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction InputOTPSlot({\n index,\n className,\n ...props\n}: React.ComponentProps<\"div\"> & {\n index: number\n}) {\n const inputOTPContext = React.useContext(OTPInputContext)\n const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}\n\n return (\n \n {char}\n {hasFakeCaret && (\n
\n
\n
\n )}\n
\n )\n}\n\nfunction InputOTPSeparator({ ...props }: React.ComponentProps<\"div\">) {\n return (\n \n \n
\n )\n}\n\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/input-otp/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/input.json b/public/r/react/styles/base-luma/input.json new file mode 100644 index 000000000..fce9e2c53 --- /dev/null +++ b/public/r/react/styles/base-luma/input.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "input", + "title": "Input", + "description": "Displays a form input field or a component that looks like an input field.", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/input.tsx", + "content": "import * as React from \"react\"\nimport { Input as InputPrimitive } from \"@base-ui/react/input\"\nimport { cn } from \"cn\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n \n )\n}\n\nexport { Input }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/input/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/item-examples.json b/public/r/react/styles/base-luma/item-examples.json new file mode 100644 index 000000000..d707c882c --- /dev/null +++ b/public/r/react/styles/base-luma/item-examples.json @@ -0,0 +1,81 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "item-examples", + "title": "Item examples", + "description": "The examples from the shadcn/ui Item docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/item", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/item/item-avatar.tsx", + "content": "import { Plus } from \"lucide-react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nexport function ItemAvatar() {\n return (\n
\n \n \n \n \n ER\n \n \n \n Evil Rabbit\n Last seen 5 months ago\n \n \n \n \n \n \n \n \n \n
\n \n \n CN\n \n \n \n LR\n \n \n \n ER\n \n
\n
\n \n No Team Members\n \n Invite your team to collaborate on this project.\n \n \n \n \n \n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-demo.tsx", + "content": "import { BadgeCheckIcon, ChevronRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nexport function ItemDemo() {\n return (\n
\n \n \n Basic Item\n \n A simple item with title and description.\n \n \n \n \n \n \n }>\n \n \n \n \n Your profile has been verified.\n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-dropdown.tsx", + "content": "\"use client\"\n\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n Item,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nconst people = [\n {\n username: \"shadcn\",\n avatar: \"https://github.com/shadcn.png\",\n email: \"shadcn@vercel.com\",\n },\n {\n username: \"maxleiter\",\n avatar: \"https://github.com/maxleiter.png\",\n email: \"maxleiter@vercel.com\",\n },\n {\n username: \"evilrabbit\",\n avatar: \"https://github.com/evilrabbit.png\",\n email: \"evilrabbit@vercel.com\",\n },\n]\n\nexport function ItemDropdown() {\n return (\n \n }>\n Select \n \n \n \n {people.map((person) => (\n \n \n \n \n \n {person.username.charAt(0)}\n \n \n \n {person.username}\n \n {person.email}\n \n \n \n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-group.tsx", + "content": "import * as React from \"react\"\nimport { PlusIcon } from \"lucide-react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemGroup,\n ItemMedia,\n ItemSeparator,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nconst people = [\n {\n username: \"shadcn\",\n avatar: \"https://github.com/shadcn.png\",\n email: \"shadcn@vercel.com\",\n },\n {\n username: \"maxleiter\",\n avatar: \"https://github.com/maxleiter.png\",\n email: \"maxleiter@vercel.com\",\n },\n {\n username: \"evilrabbit\",\n avatar: \"https://github.com/evilrabbit.png\",\n email: \"evilrabbit@vercel.com\",\n },\n]\n\nexport function ItemGroupExample() {\n return (\n \n {people.map((person, index) => (\n \n \n \n \n {person.username.charAt(0)}\n \n \n \n {person.username}\n {person.email}\n \n \n \n \n \n ))}\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-header.tsx", + "content": "import {\n Item,\n ItemContent,\n ItemDescription,\n ItemGroup,\n ItemHeader,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nconst models = [\n {\n name: \"v0-1.5-sm\",\n description: \"Everyday tasks and UI generation.\",\n image:\n \"https://images.unsplash.com/photo-1650804068570-7fb2e3dbf888?q=80&w=640&auto=format&fit=crop\",\n credit: \"Valeria Reverdo on Unsplash\",\n },\n {\n name: \"v0-1.5-lg\",\n description: \"Advanced thinking or reasoning.\",\n image:\n \"https://images.unsplash.com/photo-1610280777472-54133d004c8c?q=80&w=640&auto=format&fit=crop\",\n credit: \"Michael Oeser on Unsplash\",\n },\n {\n name: \"v0-2.0-mini\",\n description: \"Open Source model for everyone.\",\n image:\n \"https://images.unsplash.com/photo-1602146057681-08560aee8cde?q=80&w=640&auto=format&fit=crop\",\n credit: \"Cherry Laithang on Unsplash\",\n },\n]\n\nexport function ItemHeaderDemo() {\n return (\n
\n \n {models.map((model) => (\n \n \n \n \n \n {model.name}\n {model.description}\n \n \n ))}\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-icon.tsx", + "content": "import { ShieldAlertIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nexport function ItemIcon() {\n return (\n
\n \n \n \n \n \n Security Alert\n \n New login detected from unknown device.\n \n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-image.tsx", + "content": "import {\n Item,\n ItemContent,\n ItemDescription,\n ItemGroup,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nconst music = [\n {\n title: \"Midnight City Lights\",\n artist: \"Neon Dreams\",\n album: \"Electric Nights\",\n duration: \"3:45\",\n },\n {\n title: \"Coffee Shop Conversations\",\n artist: \"The Morning Brew\",\n album: \"Urban Stories\",\n duration: \"4:05\",\n },\n {\n title: \"Digital Rain\",\n artist: \"Cyber Symphony\",\n album: \"Binary Beats\",\n duration: \"3:30\",\n },\n]\n\nexport function ItemImage() {\n return (\n
\n \n {music.map((song) => (\n }\n role=\"listitem\"\n >\n \n \n \n \n \n {song.title} -{\" \"}\n {song.album}\n \n {song.artist}\n \n \n {song.duration}\n \n \n ))}\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-link.tsx", + "content": "import { ChevronRightIcon, ExternalLinkIcon } from \"lucide-react\"\n\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nexport function ItemLink() {\n return (\n
\n }>\n \n Visit our documentation\n \n Learn how to get started with our components.\n \n \n \n \n \n \n }\n >\n \n External resource\n \n Opens in a new tab with security attributes.\n \n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { BadgeCheckIcon, ChevronRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Item,\n ItemActions,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n basicItem: \"Basic Item\",\n basicItemDesc: \"A simple item with title and description.\",\n action: \"Action\",\n verifiedTitle: \"Your profile has been verified.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n basicItem: \"عنصر أساسي\",\n basicItemDesc: \"عنصر بسيط يحتوي على عنوان ووصف.\",\n action: \"إجراء\",\n verifiedTitle: \"تم التحقق من ملفك الشخصي.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n basicItem: \"פריט בסיסי\",\n basicItemDesc: \"פריט פשוט עם כותרת ותיאור.\",\n action: \"פעולה\",\n verifiedTitle: \"הפרופיל שלך אומת.\",\n },\n },\n}\n\nexport function ItemRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n
\n \n \n {t.basicItem}\n {t.basicItemDesc}\n \n \n \n \n \n } dir={dir}>\n \n \n \n \n {t.verifiedTitle}\n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-size.tsx", + "content": "import { InboxIcon } from \"lucide-react\"\n\nimport {\n Item,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nexport function ItemSizeDemo() {\n return (\n
\n \n \n \n \n \n Default Size\n \n The standard size for most use cases.\n \n \n \n \n \n \n \n \n Small Size\n A compact size for dense layouts.\n \n \n \n \n \n \n \n Extra Small Size\n The most compact size available.\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-variant.tsx", + "content": "import { InboxIcon } from \"lucide-react\"\n\nimport {\n Item,\n ItemContent,\n ItemDescription,\n ItemMedia,\n ItemTitle,\n} from \"@/components/ui/item\"\n\nexport function ItemVariant() {\n return (\n
\n \n \n \n \n \n Default Variant\n \n Transparent background with no border.\n \n \n \n \n \n \n \n \n Outline Variant\n \n Outlined style with a visible border.\n \n \n \n \n \n \n \n \n Muted Variant\n \n Muted background for secondary content.\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/item/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/item.json b/public/r/react/styles/base-luma/item.json new file mode 100644 index 000000000..f415d1f03 --- /dev/null +++ b/public/r/react/styles/base-luma/item.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "item", + "title": "Item", + "description": "A flexible container for displaying content items with various styles.", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/ui/item.tsx", + "content": "import * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction ItemGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction ItemSeparator({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nconst itemVariants = cva(\n \"[a]:hover:bg-muted rounded-2xl border text-sm group/item flex w-full flex-wrap items-center transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors\",\n {\n variants: {\n variant: {\n default: \"border-transparent\",\n outline: \"border-border\",\n muted: \"bg-muted/50 border-transparent\",\n },\n size: {\n default: \"gap-3.5 px-4 py-3.5\",\n sm: \"gap-3.5 px-3.5 py-3\",\n xs: \"gap-2.5 px-3 py-2.5 in-data-[slot=dropdown-menu-content]:p-0\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Item({\n className,\n variant = \"default\",\n size = \"default\",\n render,\n ...props\n}: useRender.ComponentProps<\"div\"> & VariantProps) {\n return useRender({\n defaultTagName: \"div\",\n props: mergeProps<\"div\">(\n {\n className: cn(itemVariants({ variant, size, className })),\n },\n props\n ),\n render,\n state: {\n slot: \"item\",\n variant,\n size,\n },\n })\n}\n\nconst itemMediaVariants = cva(\n \"gap-2 group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start flex shrink-0 items-center justify-center [&_svg]:pointer-events-none\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n icon: \"[&_svg:not([class*='size-'])]:size-4\",\n image: \"size-10 overflow-hidden rounded-xl group-data-[size=sm]/item:size-8 group-data-[size=xs]/item:size-6 group-data-[size=xs]/item:rounded-lg [&_img]:size-full [&_img]:object-cover\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction ItemMedia({\n className,\n variant = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps) {\n return (\n \n )\n}\n\nfunction ItemContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction ItemTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction ItemDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ItemActions({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction ItemHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction ItemFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nexport {\n Item,\n ItemMedia,\n ItemContent,\n ItemActions,\n ItemGroup,\n ItemSeparator,\n ItemTitle,\n ItemDescription,\n ItemHeader,\n ItemFooter,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/item/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/kbd-examples.json b/public/r/react/styles/base-luma/kbd-examples.json new file mode 100644 index 000000000..04ae9eba6 --- /dev/null +++ b/public/r/react/styles/base-luma/kbd-examples.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "kbd-examples", + "title": "Kbd examples", + "description": "The examples from the shadcn/ui Kbd docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/button-group", + "@fulldev/input-group", + "@fulldev/kbd", + "@fulldev/select", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/kbd/kbd-button.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport { Kbd } from \"@/components/ui/kbd\"\n\nexport function KbdButton() {\n return (\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-demo.tsx", + "content": "import { Kbd, KbdGroup } from \"@/components/ui/kbd\"\n\nexport function KbdDemo() {\n return (\n
\n \n ⌘\n ⇧\n ⌥\n ⌃\n \n \n Ctrl\n +\n B\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-group.tsx", + "content": "import { Kbd, KbdGroup } from \"@/components/ui/kbd\"\n\nexport function KbdGroupExample() {\n return (\n
\n

\n Use{\" \"}\n \n Ctrl + B\n Ctrl + K\n {\" \"}\n to open the command palette\n

\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-input-group.tsx", + "content": "import { SearchIcon } from \"lucide-react\"\n\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport { Kbd } from \"@/components/ui/kbd\"\n\nexport function KbdInputGroup() {\n return (\n
\n \n \n \n \n \n \n ⌘\n K\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Kbd, KbdGroup } from \"@/components/ui/kbd\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {},\n },\n ar: {\n dir: \"rtl\",\n values: {},\n },\n he: {\n dir: \"rtl\",\n values: {},\n },\n}\n\nexport function KbdRtl() {\n const { dir } = useTranslation(translations, \"ar\")\n\n return (\n
\n \n ⌘\n ⇧\n ⌥\n ⌃\n \n \n Ctrl\n +\n B\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-tooltip.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport { ButtonGroup } from \"@/components/ui/button-group\"\nimport { Kbd, KbdGroup } from \"@/components/ui/kbd\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\n\nexport function KbdTooltip() {\n return (\n
\n \n \n }>\n Save\n \n \n Save Changes S\n \n \n \n }>\n Print\n \n \n Print Document{\" \"}\n \n Ctrl\n P\n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/kbd/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/kbd.json b/public/r/react/styles/base-luma/kbd.json new file mode 100644 index 000000000..c10376497 --- /dev/null +++ b/public/r/react/styles/base-luma/kbd.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "kbd", + "title": "Kbd", + "description": "Used to display textual user input from keyboard.", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/kbd.tsx", + "content": "import { cn } from \"cn\"\n\nfunction Kbd({ className, ...props }: React.ComponentProps<\"kbd\">) {\n return (\n \n )\n}\n\nfunction KbdGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nexport { Kbd, KbdGroup }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/kbd/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/label-examples.json b/public/r/react/styles/base-luma/label-examples.json new file mode 100644 index 000000000..3a8aab06f --- /dev/null +++ b/public/r/react/styles/base-luma/label-examples.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "label-examples", + "title": "Label examples", + "description": "The examples from the shadcn/ui Label docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/checkbox", + "@fulldev/label", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/label/label-demo.tsx", + "content": "import { Checkbox } from \"@/components/ui/checkbox\"\nimport { Label } from \"@/components/ui/label\"\n\nexport function LabelDemo() {\n return (\n
\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/label/label-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport { Label } from \"@/components/ui/label\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n label: \"Accept terms and conditions\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n label: \"قبول الشروط والأحكام\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n label: \"קבל תנאים והגבלות\",\n },\n },\n}\n\nexport function LabelRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n
\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/label/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/label.json b/public/r/react/styles/base-luma/label.json new file mode 100644 index 000000000..bfc4f69bc --- /dev/null +++ b/public/r/react/styles/base-luma/label.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "label", + "title": "Label", + "description": "Renders an accessible label associated with a control.", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/label.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nfunction Label({ className, ...props }: React.ComponentProps<\"label\">) {\n return (\n \n )\n}\n\nexport { Label }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/label/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/layout.json b/public/r/react/styles/base-luma/layout.json new file mode 100644 index 000000000..c28b23123 --- /dev/null +++ b/public/r/react/styles/base-luma/layout.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "layout", + "title": "Layout", + "description": "Page-shell primitives for the root html, head, body, and main structure.", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/layout.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nfunction Layout({\n className,\n lang = \"en\",\n ...props\n}: React.ComponentProps<\"html\">) {\n return (\n \n )\n}\n\ntype LayoutImage = {\n src: string\n alt?: string\n width?: number\n height?: number\n type?: string\n}\n\n// Page metadata for search engines and link previews. `canonical` is the\n// page's absolute URL; relative image sources resolve against it.\nfunction LayoutHead({\n children,\n name,\n title,\n description,\n image,\n noindex,\n nofollow,\n canonical,\n ...props\n}: React.ComponentProps<\"head\"> & {\n name?: string\n title?: string\n description?: string\n image?: LayoutImage\n noindex?: boolean\n nofollow?: boolean\n canonical?: string\n}) {\n const imageUrl = image?.src\n ? canonical\n ? new URL(image.src, canonical).toString()\n : image.src\n : undefined\n const robots = [\n noindex === undefined ? \"\" : noindex ? \"noindex\" : \"index\",\n nofollow === undefined ? \"\" : nofollow ? \"nofollow\" : \"follow\",\n ]\n .filter(Boolean)\n .join(\",\")\n\n return (\n \n \n \n {title && {title}}\n {description && }\n {canonical && }\n {robots && }\n {title && }\n {description && }\n {canonical && }\n \n {name && }\n {imageUrl && }\n {imageUrl?.startsWith(\"https://\") && (\n \n )}\n {imageUrl && image?.alt && (\n \n )}\n {imageUrl && image?.width && (\n \n )}\n {imageUrl && image?.height && (\n \n )}\n {imageUrl && image?.type && (\n \n )}\n \n {children}\n \n )\n}\n\nfunction LayoutBody({ className, ...props }: React.ComponentProps<\"body\">) {\n return (\n \n )\n}\n\nfunction LayoutMain({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n \n )\n}\n\nexport { Layout, LayoutBody, LayoutHead, LayoutMain }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/layout/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/links-2.json b/public/r/react/styles/base-luma/links-2.json new file mode 100644 index 000000000..6a9cfd2f3 --- /dev/null +++ b/public/r/react/styles/base-luma/links-2.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "links-2", + "title": "Links 2", + "description": "Link grid blocks for presenting related pages, components, or resources.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/links-2.tsx", + "content": "import * as React from \"react\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Links2({\n title,\n description,\n links,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n links: {\n href: string\n title: string\n description: string\n }[]\n}) {\n return (\n
\n \n
\n

\n {title}\n

\n

\n {description}\n

\n
\n
\n {links.map((item) => (\n \n \n {item.title}\n \n \n \n {item.description}\n \n \n ))}\n
\n
\n
\n )\n}\n\nexport { Links2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/links/", + "categories": [ + "links" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/logo.json b/public/r/react/styles/base-luma/logo.json new file mode 100644 index 000000000..33696e005 --- /dev/null +++ b/public/r/react/styles/base-luma/logo.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "logo", + "title": "Logo", + "description": "A component for displaying a brand logo.", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/logo.tsx", + "content": "import * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cn } from \"cn\"\n\nfunction Logo({ className, render, ...props }: useRender.ComponentProps<\"a\">) {\n return useRender({\n // A logo with a destination is a link, otherwise a plain container.\n defaultTagName: props.href == null ? \"div\" : \"a\",\n props: mergeProps<\"a\">(\n {\n className: cn(\n \"text-base font-semibold flex h-10 items-center justify-start gap-2 whitespace-nowrap\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"logo\",\n },\n })\n}\n\nfunction LogoImage({\n className,\n src,\n srcLight,\n srcDark,\n alt = \"\",\n ...props\n}: React.ComponentProps<\"img\"> & {\n srcLight?: string\n srcDark?: string\n}) {\n const classes = \"h-6 w-auto shrink-0 object-contain\"\n if (srcLight && srcDark) {\n return (\n <>\n \n \n \n )\n }\n if (!src) return null\n return (\n \n )\n}\n\nfunction LogoText({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n \n )\n}\n\nexport { Logo, LogoImage, LogoText }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/logo/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/logos-1.json b/public/r/react/styles/base-luma/logos-1.json new file mode 100644 index 000000000..3c74dd229 --- /dev/null +++ b/public/r/react/styles/base-luma/logos-1.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "logos-1", + "title": "Logos 1", + "description": "Logo sections for trust, partner strips, and quiet social proof.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/logo", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/logos-1.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { Logo, LogoText } from \"@/components/ui/logo\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Logos1({\n title,\n description,\n brands,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n brands: {\n name: string\n href?: string\n }[]\n}) {\n return (\n
\n \n
\n {title}\n {description}\n
\n
    \n {brands.map((brand) => (\n
  • \n \n {brand.name}\n \n
  • \n ))}\n
\n
\n
\n )\n}\n\nexport { Logos1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/logos/", + "categories": [ + "logos" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/logos-2.json b/public/r/react/styles/base-luma/logos-2.json new file mode 100644 index 000000000..01c0c85c0 --- /dev/null +++ b/public/r/react/styles/base-luma/logos-2.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "logos-2", + "title": "Logos 2", + "description": "Logo sections for trust, partner strips, and quiet social proof.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/logo", + "@fulldev/marquee", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/logos-2.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { Logo, LogoText } from \"@/components/ui/logo\"\nimport {\n Marquee,\n MarqueeContent,\n MarqueeItem,\n MarqueeToggle,\n} from \"@/components/ui/marquee\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Logos2({\n title,\n description,\n brands,\n labels,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n brands: {\n name: string\n href?: string\n }[]\n labels: {\n play: string\n pause: string\n }\n}) {\n return (\n
\n \n {title}\n \n {description}\n \n \n \n \n \n \n \n {brands.map((brand) => (\n \n \n {brand.name}\n \n \n ))}\n \n \n
\n )\n}\n\nexport { Logos2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/logos/", + "categories": [ + "logos" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/logos-3.json b/public/r/react/styles/base-luma/logos-3.json new file mode 100644 index 000000000..7a7dd3958 --- /dev/null +++ b/public/r/react/styles/base-luma/logos-3.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "logos-3", + "title": "Logos 3", + "description": "Logo sections for trust, partner strips, and quiet social proof.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/logo", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/logos-3.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { Logo, LogoText } from \"@/components/ui/logo\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Logos3({\n className,\n brands,\n ...props\n}: React.ComponentProps<\"section\"> & {\n brands: {\n name: string\n href?: string\n }[]\n}) {\n return (\n
\n \n
    \n {brands.map((brand) => (\n
  • \n \n {brand.name}\n \n
  • \n ))}\n
\n
\n
\n )\n}\n\nexport { Logos3 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/logos/", + "categories": [ + "logos" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/marker-examples.json b/public/r/react/styles/base-luma/marker-examples.json new file mode 100644 index 000000000..0872cee0d --- /dev/null +++ b/public/r/react/styles/base-luma/marker-examples.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "marker-examples", + "title": "Marker examples", + "description": "The examples from the shadcn/ui Marker docs.", + "dependencies": [ + "lucide-react", + "sonner" + ], + "registryDependencies": [ + "@fulldev/marker", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/marker/marker-border.tsx", + "content": "import { FileTextIcon, GitBranchIcon, SearchIcon } from \"lucide-react\"\n\nimport { Marker, MarkerContent, MarkerIcon } from \"@/components/ui/marker\"\n\nexport function MarkerBorderDemo() {\n return (\n
\n \n \n \n \n Switched to release-candidate\n \n \n \n \n \n Reviewed 8 related files\n \n \n \n \n \n Opened implementation notes\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-demo.tsx", + "content": "import { GitBranchIcon, SearchIcon } from \"lucide-react\"\n\nimport { Marker, MarkerContent, MarkerIcon } from \"@/components/ui/marker\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\nexport function MarkerDemo() {\n return (\n
\n \n \n \n \n Switched to a new branch\n \n \n \n \n \n Thinking...\n \n \n Conversation compacted\n \n \n \n \n \n Explored 4 files\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-icon.tsx", + "content": "import { BookOpenCheck, GitBranchIcon, SearchIcon } from \"lucide-react\"\n\nimport { Marker, MarkerContent, MarkerIcon } from \"@/components/ui/marker\"\n\nexport function MarkerIconDemo() {\n return (\n
\n \n \n \n \n Switched to a new branch\n \n \n \n \n \n Explored 4 files\n \n \n \n \n \n Syncing completed\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-link-button.tsx", + "content": "\"use client\"\n\nimport { GitBranchIcon, RotateCcwIcon } from \"lucide-react\"\nimport { toast } from \"sonner\"\n\nimport { Marker, MarkerContent, MarkerIcon } from \"@/components/ui/marker\"\n\nexport function MarkerLinkButtonDemo() {\n return (\n
\n }>\n \n \n \n View the pull request\n \n toast(\"You clicked the revert button\")}\n />\n }\n >\n \n \n \n Revert this change\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-separator.tsx", + "content": "import { Marker, MarkerContent } from \"@/components/ui/marker\"\n\nexport function MarkerSeparatorDemo() {\n return (\n
\n \n Today\n \n \n Worked for 42s\n \n \n Conversation compacted\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-shimmer.tsx", + "content": "import { Marker, MarkerContent } from \"@/components/ui/marker\"\n\nexport function MarkerShimmerDemo() {\n return (\n
\n \n Thinking...\n \n \n Reading 4 files\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-status.tsx", + "content": "import { Marker, MarkerContent, MarkerIcon } from \"@/components/ui/marker\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\nexport function MarkerStatusDemo() {\n return (\n
\n \n \n \n \n Compacting conversation\n \n \n \n \n \n Running tests\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-variants.tsx", + "content": "import { Marker, MarkerContent } from \"@/components/ui/marker\"\n\nexport function MarkerVariantsDemo() {\n return (\n
\n \n A default marker for inline notes.\n \n \n A separator marker\n \n \n A border marker for row boundaries.\n \n
\n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/marker/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/marker.json b/public/r/react/styles/base-luma/marker.json new file mode 100644 index 000000000..cbd9ab956 --- /dev/null +++ b/public/r/react/styles/base-luma/marker.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "marker", + "title": "Marker", + "description": "Marks a status or event in a conversation, with an icon and text.", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/marker.tsx", + "content": "import * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nconst markerVariants = cva(\n \"gap-2 text-sm text-muted-foreground [a]:hover:text-foreground [a]:underline-offset-3 [a]:underline [&_svg:not([class*='size-'])]:size-4 min-h-4 text-left group/marker relative flex w-full items-center\",\n {\n variants: {\n variant: {\n default: \"\",\n separator: \"before:h-px before:min-w-0 before:flex-1 before:bg-border after:h-px after:min-w-0 after:flex-1 after:bg-border before:mr-1 after:ml-1\",\n border: \"border-b border-border pb-2\",\n },\n },\n }\n)\n\nfunction Marker({\n className,\n variant = \"default\",\n render,\n ...props\n}: useRender.ComponentProps<\"div\"> & VariantProps) {\n return useRender({\n defaultTagName: \"div\",\n props: mergeProps<\"div\">(\n {\n className: cn(markerVariants({ variant, className })),\n },\n props\n ),\n render,\n state: {\n slot: \"marker\",\n variant,\n },\n })\n}\n\nfunction MarkerIcon({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n \n )\n}\n\nfunction MarkerContent({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n \n )\n}\n\nexport { Marker, MarkerIcon, MarkerContent, markerVariants }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/marker/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/marquee.json b/public/r/react/styles/base-luma/marquee.json new file mode 100644 index 000000000..713c4cf84 --- /dev/null +++ b/public/r/react/styles/base-luma/marquee.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "marquee", + "title": "Marquee", + "description": "A continuously scrolling row of content, with a pause control and a static fallback.", + "dependencies": [ + "class-variance-authority", + "cn", + "embla-carousel-auto-scroll@8.6.0", + "embla-carousel-react@8.6.0", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/marquee.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\nimport AutoScroll from \"embla-carousel-auto-scroll\"\nimport useEmblaCarousel from \"embla-carousel-react\"\nimport { PauseIcon, PlayIcon } from \"lucide-react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\n\ntype MarqueeContextProps = {\n // Rows may move: motion is allowed and a toggle can pause them.\n canMove: boolean\n playing: boolean\n hovered: boolean\n moving: boolean\n pause: () => void\n toggle: () => void\n setHovered: (hovered: boolean) => void\n setRowMoving: (id: string, moving: boolean) => void\n registerToggle: (toggle: HTMLButtonElement) => () => void\n}\n\nconst MarqueeContext = React.createContext(null)\n\nfunction useMarquee() {\n const context = React.useContext(MarqueeContext)\n if (!context) {\n throw new Error(\"useMarquee must be used within a \")\n }\n return context\n}\n\n// One callback ref for several refs. A callback ref's own cleanup runs when\n// the node detaches (React 19); other refs are set back to null.\nfunction composeRefs(...refs: (React.Ref | undefined)[]) {\n return (node: T | null) => {\n const cleanups = refs.map((ref) => {\n if (typeof ref === \"function\") {\n const cleanup = ref(node)\n return typeof cleanup === \"function\" ? cleanup : () => ref(null)\n }\n if (ref) {\n ref.current = node\n return () => {\n ref.current = null\n }\n }\n })\n return () => cleanups.forEach((cleanup) => cleanup?.())\n }\n}\n\nconst reducedMotionQuery = \"(prefers-reduced-motion: reduce)\"\n\nfunction subscribeReducedMotion(onChange: () => void) {\n const query = window.matchMedia(reducedMotionQuery)\n query.addEventListener(\"change\", onChange)\n return () => query.removeEventListener(\"change\", onChange)\n}\n\n// The server renders the static fallback; the browser decides after hydration.\nfunction useReducedMotion() {\n return React.useSyncExternalStore(\n subscribeReducedMotion,\n () => window.matchMedia(reducedMotionQuery).matches,\n () => true\n )\n}\n\nconst visible = (element: Element) =>\n element.checkVisibility?.({ visibilityProperty: true }) ??\n element.getClientRects().length > 0\n\n// A toggle pauses the marquee when it can be pressed and seen. The marquee\n// hides a toggle through its own wrapper, so visibility is read from the\n// button's styles and from the wrapper's parent.\nfunction usable(toggle: HTMLButtonElement) {\n const style = getComputedStyle(toggle)\n const outside = toggle.closest(\"[data-marquee-control]\")?.parentElement\n return (\n !toggle.matches(\":disabled\") &&\n toggle.getAttribute(\"aria-disabled\") !== \"true\" &&\n !toggle.closest(\"[inert]\") &&\n style.display !== \"none\" &&\n style.visibility !== \"hidden\" &&\n outside != null &&\n visible(outside)\n )\n}\n\nfunction Marquee({\n className,\n ref,\n onFocus,\n ...props\n}: React.ComponentProps<\"div\">) {\n const root = React.useRef(null)\n const setRoot = React.useMemo(() => composeRefs(root, ref), [ref])\n const reducedMotion = useReducedMotion()\n const [toggles, setToggles] = React.useState([])\n const [controllable, setControllable] = React.useState(false)\n // Focus, dragging and the toggle pause the rows until the toggle plays\n // them again; hovering pauses them only while the pointer is over a row.\n const [playing, setPlaying] = React.useState(true)\n const [hovered, setHovered] = React.useState(false)\n const [movingRows, setMovingRows] = React.useState>(\n () => new Set()\n )\n\n const registerToggle = React.useCallback((toggle: HTMLButtonElement) => {\n setToggles((current) => [...current, toggle])\n return () =>\n setToggles((current) => current.filter((item) => item !== toggle))\n }, [])\n\n const setRowMoving = React.useCallback((id: string, moving: boolean) => {\n setMovingRows((current) => {\n if (current.has(id) === moving) return current\n const next = new Set(current)\n if (moving) next.add(id)\n else next.delete(id)\n return next\n })\n }, [])\n\n // Follow whether a toggle can still be pressed and seen: changes to the\n // toggle and its ancestors, and breakpoints that hide it or its container.\n React.useEffect(() => {\n const element = root.current\n if (!element || toggles.length === 0) {\n setControllable(false)\n return\n }\n let frame = 0\n const refresh = () => {\n cancelAnimationFrame(frame)\n frame = requestAnimationFrame(() => setControllable(toggles.some(usable)))\n }\n const resizes = new ResizeObserver(refresh)\n const mutations = new MutationObserver(refresh)\n for (const toggle of toggles) {\n for (let node: Element | null = toggle; node; node = node.parentElement) {\n if (node.hasAttribute(\"data-marquee-control\")) continue\n mutations.observe(node, {\n attributeFilter: [\n \"class\",\n \"style\",\n \"hidden\",\n \"disabled\",\n \"aria-disabled\",\n \"inert\",\n ],\n })\n if (element.contains(node)) resizes.observe(node)\n }\n }\n setControllable(toggles.some(usable))\n return () => {\n cancelAnimationFrame(frame)\n resizes.disconnect()\n mutations.disconnect()\n }\n }, [toggles])\n\n const value = React.useMemo(\n () => ({\n canMove: controllable && !reducedMotion,\n playing,\n hovered,\n moving: movingRows.size > 0,\n pause: () => setPlaying(false),\n toggle: () => setPlaying((current) => !current),\n setHovered,\n setRowMoving,\n registerToggle,\n }),\n [\n controllable,\n reducedMotion,\n playing,\n hovered,\n movingRows,\n setRowMoving,\n registerToggle,\n ]\n )\n\n return (\n \n {\n onFocus?.(event)\n const target = event.target\n if (!toggles.some((toggle) => toggle.contains(target))) {\n setPlaying(false)\n }\n }}\n {...props}\n />\n \n )\n}\n\nconst focusableSelector =\n \"a[href], area[href], button, input, select, textarea, iframe, summary, [contenteditable], [tabindex]\"\n\nconst reachable = (element: HTMLElement) =>\n element.tabIndex >= 0 &&\n !element.matches(\":disabled\") &&\n !element.closest(\"[inert]\") &&\n visible(element)\n\nfunction MarqueeContent({\n className,\n children,\n reverse = false,\n ref,\n tabIndex,\n onPointerEnter,\n onPointerLeave,\n ...props\n}: React.ComponentProps<\"div\"> & {\n reverse?: boolean\n}) {\n const marquee = useMarquee()\n const { canMove, playing, hovered, pause, setHovered, setRowMoving } = marquee\n const id = React.useId()\n const viewport = React.useRef(null)\n // Embla turns its loop off when the items do not fill the viewport; the row\n // then stays static until its size changes.\n const [fits, setFits] = React.useState(true)\n const [rtl, setRtl] = React.useState(false)\n const [looping, setLooping] = React.useState(false)\n const [generation, setGeneration] = React.useState(0)\n const [tabStop, setTabStop] = React.useState(false)\n const active = canMove && fits\n\n const options = React.useMemo(\n () => ({\n loop: true,\n dragFree: true,\n active,\n direction: rtl ? (\"rtl\" as const) : (\"ltr\" as const),\n }),\n [active, rtl]\n )\n const plugins = React.useMemo(\n () => [\n AutoScroll({\n speed: 1,\n startDelay: 0,\n playOnInit: false,\n stopOnFocusIn: false,\n stopOnInteraction: true,\n direction: reverse ? \"backward\" : \"forward\",\n }),\n ],\n [reverse]\n )\n const [emblaRef, api] = useEmblaCarousel(options, plugins)\n\n const setViewport = React.useMemo(\n () => composeRefs(viewport, emblaRef, ref),\n [emblaRef, ref]\n )\n\n React.useEffect(() => {\n if (!api) return\n const update = () => {\n const loops =\n api.internalEngine().options.active &&\n api.internalEngine().options.loop &&\n api.scrollSnapList().length > 1\n if (api.internalEngine().options.active && !loops) setFits(false)\n setLooping(loops)\n setGeneration((current) => current + 1)\n }\n update()\n api.on(\"init\", update).on(\"reInit\", update).on(\"pointerDown\", pause)\n return () => {\n api.off(\"init\", update).off(\"reInit\", update).off(\"pointerDown\", pause)\n }\n }, [api, pause])\n\n React.useEffect(() => {\n setRowMoving(id, looping)\n return () => setRowMoving(id, false)\n }, [id, looping, setRowMoving])\n\n React.useEffect(() => {\n if (!api || !looping) return\n const autoScroll = api.plugins().autoScroll\n if (playing && !hovered) autoScroll?.play()\n else autoScroll?.stop()\n }, [api, looping, playing, hovered, generation])\n\n // A static row scrolls natively. It gets a tab stop when it overflows and\n // has no reachable content of its own, unless the caller set tabIndex.\n React.useEffect(() => {\n const element = viewport.current\n if (!element) return\n const measure = () => {\n setRtl(getComputedStyle(element).direction === \"rtl\")\n setTabStop(\n element.scrollWidth > element.clientWidth &&\n ![...element.querySelectorAll(focusableSelector)].some(\n reachable\n )\n )\n }\n const observer = new ResizeObserver(() => {\n measure()\n setFits(true)\n })\n observer.observe(element)\n for (const item of element.firstElementChild?.children ?? []) {\n observer.observe(item)\n }\n measure()\n return () => observer.disconnect()\n }, [children])\n\n return (\n {\n onPointerEnter?.(event)\n if (event.pointerType === \"mouse\") setHovered(true)\n }}\n onPointerLeave={(event) => {\n onPointerLeave?.(event)\n setHovered(false)\n }}\n {...props}\n >\n
\n {children}\n
\n \n )\n}\n\nfunction MarqueeItem({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction MarqueeToggle({\n className,\n variant = \"outline\",\n size = \"icon-sm\",\n playLabel,\n pauseLabel,\n ref,\n onClick,\n ...props\n}: Omit, \"type\"> &\n VariantProps & {\n playLabel: string\n pauseLabel: string\n }) {\n const { moving, playing, toggle, registerToggle } = useMarquee()\n const button = React.useRef(null)\n\n React.useEffect(() => {\n if (button.current) return registerToggle(button.current)\n }, [registerToggle])\n\n const setButton = React.useMemo(() => composeRefs(button, ref), [ref])\n\n // The wrapper shows the toggle while a row moves, so the button's own\n // hidden attribute, class and style stay the caller's.\n return (\n \n )\n}\n\nexport { Marquee, MarqueeContent, MarqueeItem, MarqueeToggle, useMarquee }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/marquee/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/menubar-examples.json b/public/r/react/styles/base-luma/menubar-examples.json new file mode 100644 index 000000000..1ff123370 --- /dev/null +++ b/public/r/react/styles/base-luma/menubar-examples.json @@ -0,0 +1,53 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "menubar-examples", + "title": "Menubar examples", + "description": "The examples from the shadcn/ui Menubar docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/menubar", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/menubar/menubar-checkbox.tsx", + "content": "import {\n Menubar,\n MenubarCheckboxItem,\n MenubarContent,\n MenubarItem,\n MenubarMenu,\n MenubarSeparator,\n MenubarShortcut,\n MenubarTrigger,\n} from \"@/components/ui/menubar\"\n\nexport function MenubarCheckbox() {\n return (\n \n \n View\n \n Always Show Bookmarks Bar\n \n Always Show Full URLs\n \n \n \n Reload ⌘R\n \n \n Force Reload ⇧⌘R\n \n \n \n \n Format\n \n Strikethrough\n Code\n Superscript\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/menubar/menubar-demo.tsx", + "content": "import {\n Menubar,\n MenubarCheckboxItem,\n MenubarContent,\n MenubarGroup,\n MenubarItem,\n MenubarMenu,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarTrigger,\n} from \"@/components/ui/menubar\"\n\nexport function MenubarDemo() {\n return (\n \n \n File\n \n \n \n New Tab ⌘T\n \n \n New Window ⌘N\n \n New Incognito Window\n \n \n \n \n Share\n \n \n Email link\n Messages\n Notes\n \n \n \n \n \n \n \n Print... ⌘P\n \n \n \n \n \n Edit\n \n \n \n Undo ⌘Z\n \n \n Redo ⇧⌘Z\n \n \n \n \n \n Find\n \n \n Search the web\n \n \n \n Find...\n Find Next\n Find Previous\n \n \n \n \n \n \n Cut\n Copy\n Paste\n \n \n \n \n View\n \n \n Bookmarks Bar\n Full URLs\n \n \n \n \n Reload ⌘R\n \n \n Force Reload ⇧⌘R\n \n \n \n \n Toggle Fullscreen\n \n \n \n Hide Sidebar\n \n \n \n \n Profiles\n \n \n Andy\n Benoit\n Luis\n \n \n \n Edit...\n \n \n \n Add Profile...\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/menubar/menubar-icons.tsx", + "content": "import {\n FileIcon,\n FolderIcon,\n HelpCircleIcon,\n SaveIcon,\n SettingsIcon,\n TrashIcon,\n} from \"lucide-react\"\n\nimport {\n Menubar,\n MenubarContent,\n MenubarGroup,\n MenubarItem,\n MenubarMenu,\n MenubarSeparator,\n MenubarShortcut,\n MenubarTrigger,\n} from \"@/components/ui/menubar\"\n\nexport function MenubarIcons() {\n return (\n \n \n File\n \n \n \n New File ⌘N\n \n \n \n Open Folder\n \n \n \n \n Save ⌘S\n \n \n \n \n More\n \n \n \n \n Settings\n \n \n \n Help\n \n \n \n \n Delete\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/menubar/menubar-radio.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Menubar,\n MenubarContent,\n MenubarItem,\n MenubarMenu,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSeparator,\n MenubarTrigger,\n} from \"@/components/ui/menubar\"\n\nexport function MenubarRadio() {\n const [user, setUser] = React.useState(\"benoit\")\n const [theme, setTheme] = React.useState(\"system\")\n\n return (\n \n \n Profiles\n \n \n Andy\n Benoit\n Luis\n \n \n Edit...\n Add Profile...\n \n \n \n Theme\n \n \n Light\n Dark\n System\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/menubar/menubar-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Menubar,\n MenubarCheckboxItem,\n MenubarContent,\n MenubarGroup,\n MenubarItem,\n MenubarMenu,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarTrigger,\n} from \"@/components/ui/menubar\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n file: \"File\",\n newTab: \"New Tab\",\n newWindow: \"New Window\",\n newIncognitoWindow: \"New Incognito Window\",\n share: \"Share\",\n emailLink: \"Email link\",\n messages: \"Messages\",\n notes: \"Notes\",\n print: \"Print...\",\n edit: \"Edit\",\n undo: \"Undo\",\n redo: \"Redo\",\n find: \"Find\",\n searchTheWeb: \"Search the web\",\n findItem: \"Find...\",\n findNext: \"Find Next\",\n findPrevious: \"Find Previous\",\n cut: \"Cut\",\n copy: \"Copy\",\n paste: \"Paste\",\n view: \"View\",\n bookmarksBar: \"Bookmarks Bar\",\n fullUrls: \"Full URLs\",\n reload: \"Reload\",\n forceReload: \"Force Reload\",\n toggleFullscreen: \"Toggle Fullscreen\",\n hideSidebar: \"Hide Sidebar\",\n profiles: \"Profiles\",\n andy: \"Andy\",\n benoit: \"Benoit\",\n luis: \"Luis\",\n editProfile: \"Edit...\",\n addProfile: \"Add Profile...\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n file: \"ملف\",\n newTab: \"علامة تبويب جديدة\",\n newWindow: \"نافذة جديدة\",\n newIncognitoWindow: \"نافذة التصفح المتخفي الجديدة\",\n share: \"مشاركة\",\n emailLink: \"رابط البريد الإلكتروني\",\n messages: \"الرسائل\",\n notes: \"الملاحظات\",\n print: \"طباعة...\",\n edit: \"تعديل\",\n undo: \"تراجع\",\n redo: \"إعادة\",\n find: \"بحث\",\n searchTheWeb: \"البحث على الويب\",\n findItem: \"بحث...\",\n findNext: \"البحث التالي\",\n findPrevious: \"البحث السابق\",\n cut: \"قص\",\n copy: \"نسخ\",\n paste: \"لصق\",\n view: \"عرض\",\n bookmarksBar: \"شريط الإشارات المرجعية\",\n fullUrls: \"عناوين URL الكاملة\",\n reload: \"إعادة تحميل\",\n forceReload: \"إعادة تحميل قسري\",\n toggleFullscreen: \"تبديل وضع ملء الشاشة\",\n hideSidebar: \"إخفاء الشريط الجانبي\",\n profiles: \"الملفات الشخصية\",\n andy: \"Andy\",\n benoit: \"Benoit\",\n luis: \"Luis\",\n editProfile: \"تعديل...\",\n addProfile: \"إضافة ملف شخصي...\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n file: \"קובץ\",\n newTab: \"כרטיסייה חדשה\",\n newWindow: \"חלון חדש\",\n newIncognitoWindow: \"חלון גלישה בסתר חדש\",\n share: \"שתף\",\n emailLink: \"קישור אימייל\",\n messages: \"הודעות\",\n notes: \"הערות\",\n print: \"הדפס...\",\n edit: \"ערוך\",\n undo: \"בטל\",\n redo: \"בצע שוב\",\n find: \"מצא\",\n searchTheWeb: \"חפש באינטרנט\",\n findItem: \"מצא...\",\n findNext: \"מצא הבא\",\n findPrevious: \"מצא הקודם\",\n cut: \"גזור\",\n copy: \"העתק\",\n paste: \"הדבק\",\n view: \"תצוגה\",\n bookmarksBar: \"סרגל סימניות\",\n fullUrls: \"כתובות URL מלאות\",\n reload: \"רענן\",\n forceReload: \"רענן בכוח\",\n toggleFullscreen: \"החלף מסך מלא\",\n hideSidebar: \"הסתר סרגל צד\",\n profiles: \"פרופילים\",\n andy: \"Andy\",\n benoit: \"Benoit\",\n luis: \"Luis\",\n editProfile: \"ערוך...\",\n addProfile: \"הוסף פרופיל...\",\n },\n },\n}\n\nexport function MenubarRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n const [profile, setProfile] = React.useState(\"benoit\")\n\n return (\n \n \n {t.file}\n \n \n \n {t.newTab} ⌘T\n \n \n {t.newWindow} ⌘N\n \n {t.newIncognitoWindow}\n \n \n \n \n {t.share}\n \n \n {t.emailLink}\n {t.messages}\n {t.notes}\n \n \n \n \n \n \n \n {t.print} ⌘P\n \n \n \n \n \n {t.edit}\n \n \n \n {t.undo} ⌘Z\n \n \n {t.redo} ⇧⌘Z\n \n \n \n \n \n {t.find}\n \n \n {t.searchTheWeb}\n \n \n \n {t.findItem}\n {t.findNext}\n {t.findPrevious}\n \n \n \n \n \n \n {t.cut}\n {t.copy}\n {t.paste}\n \n \n \n \n {t.view}\n \n \n {t.bookmarksBar}\n {t.fullUrls}\n \n \n \n \n {t.reload} ⌘R\n \n \n {t.forceReload} ⇧⌘R\n \n \n \n \n {t.toggleFullscreen}\n \n \n \n {t.hideSidebar}\n \n \n \n \n {t.profiles}\n \n \n {t.andy}\n {t.benoit}\n {t.luis}\n \n \n \n {t.editProfile}\n \n \n \n {t.addProfile}\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/menubar/menubar-submenu.tsx", + "content": "import {\n Menubar,\n MenubarContent,\n MenubarItem,\n MenubarMenu,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarTrigger,\n} from \"@/components/ui/menubar\"\n\nexport function MenubarSubmenu() {\n return (\n \n \n File\n \n \n Share\n \n Email link\n Messages\n Notes\n \n \n \n \n Print... ⌘P\n \n \n \n \n Edit\n \n \n Undo ⌘Z\n \n \n Redo ⇧⌘Z\n \n \n \n Find\n \n Find...\n Find Next\n Find Previous\n \n \n \n Cut\n Copy\n Paste\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/menubar/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/menubar.json b/public/r/react/styles/base-luma/menubar.json new file mode 100644 index 000000000..ba3d32154 --- /dev/null +++ b/public/r/react/styles/base-luma/menubar.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "menubar", + "title": "Menubar", + "description": "A persistent menu bar with quick access to a set of commands.", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/dropdown-menu" + ], + "files": [ + { + "path": "src/components/ui/menubar.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\"\nimport { Menubar as MenubarPrimitive } from \"@base-ui/react/menubar\"\nimport { cn } from \"cn\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nfunction Menubar({ className, ...props }: MenubarPrimitive.Props) {\n return (\n \n )\n}\n\nfunction MenubarMenu({ ...props }: React.ComponentProps) {\n return \n}\n\nfunction MenubarGroup({\n ...props\n}: React.ComponentProps) {\n return \n}\n\nfunction MenubarPortal({\n ...props\n}: React.ComponentProps) {\n return \n}\n\nfunction MenubarTrigger({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction MenubarContent({\n className,\n align = \"start\",\n alignOffset = -4,\n sideOffset = 8,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction MenubarItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction MenubarCheckboxItem({\n className,\n children,\n checked,\n inset,\n ...props\n}: MenuPrimitive.CheckboxItem.Props & {\n inset?: boolean\n}) {\n return (\n \n \n \n \n \n \n {children}\n \n )\n}\n\nfunction MenubarRadioGroup({\n ...props\n}: React.ComponentProps) {\n return \n}\n\nfunction MenubarRadioItem({\n className,\n children,\n inset,\n ...props\n}: MenuPrimitive.RadioItem.Props & {\n inset?: boolean\n}) {\n return (\n \n \n \n \n \n \n {children}\n \n )\n}\n\nfunction MenubarLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps & {\n inset?: boolean\n}) {\n return (\n \n )\n}\n\nfunction MenubarSeparator({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction MenubarShortcut({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction MenubarSub({\n ...props\n}: React.ComponentProps) {\n return \n}\n\nfunction MenubarSubTrigger({\n className,\n inset,\n ...props\n}: React.ComponentProps & {\n inset?: boolean\n}) {\n return (\n \n )\n}\n\nfunction MenubarSubContent({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nexport {\n Menubar,\n MenubarPortal,\n MenubarMenu,\n MenubarTrigger,\n MenubarContent,\n MenubarGroup,\n MenubarSeparator,\n MenubarLabel,\n MenubarItem,\n MenubarShortcut,\n MenubarCheckboxItem,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSub,\n MenubarSubTrigger,\n MenubarSubContent,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/menubar/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/message-examples.json b/public/r/react/styles/base-luma/message-examples.json new file mode 100644 index 000000000..659e167e8 --- /dev/null +++ b/public/r/react/styles/base-luma/message-examples.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "message-examples", + "title": "Message examples", + "description": "The examples from the shadcn/ui Message docs.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/attachment", + "@fulldev/avatar", + "@fulldev/bubble", + "@fulldev/button", + "@fulldev/marker", + "@fulldev/message" + ], + "files": [ + { + "path": "src/components/examples/message/message-actions.tsx", + "content": "import {\n CopyIcon,\n RefreshCcwIcon,\n ThumbsDownIcon,\n ThumbsUpIcon,\n} from \"lucide-react\"\n\nimport { Bubble, BubbleContent } from \"@/components/ui/bubble\"\nimport { Button } from \"@/components/ui/button\"\nimport { Message, MessageContent, MessageFooter } from \"@/components/ui/message\"\n\nexport function MessageActionsDemo() {\n return (\n
\n \n \n \n \n The install failure is coming from the workspace package.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Okay drop me a link. Taking a look...\n \n \n Failed to send\n \n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message/message-attachment.tsx", + "content": "\"use client\"\n\nimport { DownloadIcon, FileTextIcon } from \"lucide-react\"\n\nimport {\n Attachment,\n AttachmentAction,\n AttachmentActions,\n AttachmentContent,\n AttachmentDescription,\n AttachmentMedia,\n AttachmentTitle,\n} from \"@/components/ui/attachment\"\nimport { Bubble, BubbleContent } from \"@/components/ui/bubble\"\nimport { Message, MessageContent } from \"@/components/ui/message\"\n\nexport function MessageAttachmentDemo() {\n return (\n
\n \n \n \n \n \n \n \n \n \n Here's the image. Can you add it to the PDF? Use it for the\n cover page.\n \n \n \n \n \n \n \n \n Done. Here's the PDF with the image added as the cover page.\n \n \n \n \n \n \n \n sales-dashboard.pdf\n PDF · 2.4 MB\n \n \n \n \n \n \n \n \n \n \n \n \n Thanks. Looks good.\n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message/message-avatar.tsx", + "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Bubble, BubbleContent, BubbleGroup } from \"@/components/ui/bubble\"\nimport { Message, MessageAvatar, MessageContent } from \"@/components/ui/message\"\n\nexport function MessageAvatarDemo() {\n return (\n
\n \n \n \n \n R\n \n \n \n \n \n The build failed during dependency installation.\n \n \n \n \n \n \n \n \n R\n \n \n \n \n Can you share the exact error?\n \n \n \n \n \n \n \n R\n \n \n \n \n \n Here's the error from the logs\n \n \n \n Something went wrong with the build. The libraries are not\n installed correctly. Try running the build again.\n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message/message-demo.tsx", + "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport {\n Bubble,\n BubbleContent,\n BubbleGroup,\n BubbleReactions,\n} from \"@/components/ui/bubble\"\nimport { Marker, MarkerContent } from \"@/components/ui/marker\"\nimport {\n Message,\n MessageAvatar,\n MessageContent,\n MessageFooter,\n} from \"@/components/ui/message\"\n\nexport function MessageDemo() {\n return (\n
\n \n \n \n \n ME\n \n \n \n \n Deploying to prod real quick.\n \n \n \n \n \n \n \n R\n \n \n \n \n It's 4:55 PM. On a Friday.\n \n \n \n \n \n \n \n ME\n \n \n \n \n It's a one-line change.\n \n Delivered\n \n \n \n \n \n \n R\n \n \n \n \n \n \n It's always a one-line change 😭.\n \n \n \n Alright, let me take a look.\n \n 👍\n \n \n \n \n \n \n \n Oliver is typing...\n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message/message-group.tsx", + "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Bubble, BubbleContent } from \"@/components/ui/bubble\"\nimport {\n Message,\n MessageAvatar,\n MessageContent,\n MessageGroup,\n} from \"@/components/ui/message\"\n\nexport function MessageGroupDemo() {\n return (\n
\n \n \n \n \n \n I checked the registry addresses.\n \n \n \n \n \n \n \n CN\n \n \n \n \n \n The component and example JSON now live under the UI registry.\n \n \n \n \n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message/message-header-footer.tsx", + "content": "import { Bubble, BubbleContent } from \"@/components/ui/bubble\"\nimport {\n Message,\n MessageContent,\n MessageFooter,\n MessageHeader,\n} from \"@/components/ui/message\"\n\nexport function MessageHeaderFooterDemo() {\n return (\n
\n \n \n Olivia\n \n I already checked the logs.\n \n \n \n \n \n \n \n Send the report to the team. Ping @shadcn if you need help.\n \n \n \n
\n Read Yesterday\n
\n
\n
\n
\n
\n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/message/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/message-scroller-examples.json b/public/r/react/styles/base-luma/message-scroller-examples.json new file mode 100644 index 000000000..596157b1f --- /dev/null +++ b/public/r/react/styles/base-luma/message-scroller-examples.json @@ -0,0 +1,105 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "message-scroller-examples", + "title": "Message Scroller examples", + "description": "The examples from the shadcn/ui Message Scroller docs.", + "dependencies": [ + "@ai-sdk/react", + "@shadcn/helpers", + "ai", + "lucide-react", + "motion", + "sonner" + ], + "registryDependencies": [ + "@fulldev/bubble", + "@fulldev/button", + "@fulldev/card", + "@fulldev/dropdown-menu", + "@fulldev/empty", + "@fulldev/hover-card", + "@fulldev/input-group", + "@fulldev/marker", + "@fulldev/message", + "@fulldev/message-scroller", + "@fulldev/select", + "@fulldev/slider", + "@fulldev/tabs", + "@fulldev/toggle-group", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/message-scroller/message-scroller-anchoring.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowUpIcon,\n MessageCircleDashedIcon,\n RotateCwIcon,\n} from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport {\n Empty,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/components/ui/empty\"\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerProvider,\n MessageScrollerViewport,\n} from \"@/components/ui/message-scroller\"\nimport { ToggleGroup, ToggleGroupItem } from \"@/components/ui/toggle-group\"\nimport { MessageAnimated } from \"@/components/message-animated\"\n\ntype AnchorRole = \"user\" | \"assistant\"\n\ntype ChatMessage = {\n id: string\n role: AnchorRole\n text: string\n}\n\nconst scriptedMessages: ChatMessage[] = [\n {\n id: \"anchor-1-user\",\n role: \"user\",\n text: \"Can you show me how anchoring behaves when a new prompt starts the turn?\",\n },\n {\n id: \"anchor-1-assistant\",\n role: \"assistant\",\n text: \"Append the user prompt first, then append the assistant response. With User selected, the prompt settles near the top and the assistant response fills in below it.\",\n },\n {\n id: \"anchor-2-user\",\n role: \"user\",\n text: \"What changes when assistant messages are the anchor?\",\n },\n {\n id: \"anchor-2-assistant\",\n role: \"assistant\",\n text: \"Now each assistant response is the item `MessageScroller` keeps in view. This is useful when the reply is the moment you want readers to land on after each turn.\",\n },\n {\n id: \"anchor-3-user\",\n role: \"user\",\n text: \"Can I switch roles and keep adding turns?\",\n },\n {\n id: \"anchor-3-assistant\",\n role: \"assistant\",\n text: \"Yes. The next appended message with the selected role becomes the anchor, so you can compare user and assistant anchoring without resetting the demo.\",\n },\n]\n\nexport function MessageScrollerAnchoring() {\n const [anchorRole, setAnchorRole] = React.useState(\"user\")\n const [messages, setMessages] = React.useState([])\n const [messageIndex, setMessageIndex] = React.useState(0)\n const nextMessage = scriptedMessages[messageIndex]\n\n return (\n
\n \n \n Anchoring Turns\n \n Choose which role settles near the top edge.\n \n \n {\n setMessages([])\n setMessageIndex(0)\n }}\n >\n \n \n \n \n \n {messages.length === 0 ? (\n \n \n \n \n \n No anchored messages yet\n \n Send the first message to see the selected role anchor.\n \n \n \n ) : (\n \n \n \n \n {messages.map((message) => (\n \n ))}\n \n \n \n \n \n )}\n \n \n {\n const nextValue = value[0]\n\n if (nextValue === \"user\" || nextValue === \"assistant\") {\n setAnchorRole(nextValue)\n setMessages([])\n setMessageIndex(0)\n }\n }}\n >\n \n User\n \n \n Assistant\n \n \n {\n if (!nextMessage) {\n return\n }\n\n setMessages((messages) => [...messages, nextMessage])\n setMessageIndex((index) => index + 1)\n }}\n >\n \n Send Message\n \n \n \n
\n Toggle the anchor role, then send messages to compare where turns\n settle.\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-animation.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { useChat } from \"@ai-sdk/react\"\nimport {\n ArrowUpIcon,\n MessageCircleDashedIcon,\n RotateCwIcon,\n} from \"lucide-react\"\n\nimport { createChat } from \"@/lib/ai\"\nimport {\n MESSAGE_ANIMATIONS,\n type MessageAnimationId,\n} from \"@/lib/message-animations\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport {\n Empty,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/components/ui/empty\"\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerProvider,\n MessageScrollerViewport,\n} from \"@/components/ui/message-scroller\"\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\nimport { MessageAnimated } from \"@/components/message-animated\"\n\nconst chat = createChat()\n .user(\"Can user messages pop in like iMessage without breaking anchoring?\")\n .sleep(1000)\n .assistant(\n \"Yes. Animate the user row with transform and opacity, and let the assistant response stream normally below it.\\n\\nThat keeps the row measurement predictable while still giving the newly sent bubble a more tactile entrance.\"\n )\n .user(\"What makes the animation feel more like iMessage?\")\n .sleep(1000)\n .assistant(\n \"Use a quick spring from the trailing edge: a little scale, a small upward move, and no layout animation.\\n\\nThe bubble feels tactile, but the measured row stays predictable, so anchoring and auto-scroll do not have to fight a changing layout.\"\n )\n .user(\"Can I switch between presets while testing the same thread?\")\n .sleep(1000)\n .assistant(\n \"Yes. Keep the conversation in place while you change the preset, then send the next message to compare the new entrance against the same context.\\n\\nThat makes it easier to judge the difference between a subtle fade, a snappy pop, and a more dramatic 3D tilt without rebuilding the scenario each time.\"\n )\n\nconst initialMessages = chat.get(0)\nconst transport = chat.transport({ delayMs: 15 })\n\nexport function MessageScrollerAnimation() {\n const { messages, sendMessage, setMessages, status } = useChat({\n messages: initialMessages,\n transport,\n })\n const [presetId, setPresetId] = React.useState(\"fade\")\n const nextMessage = chat.next(messages)\n const isBusy = status === \"submitted\" || status === \"streaming\"\n const preset = MESSAGE_ANIMATIONS[presetId as MessageAnimationId]\n\n return (\n
\n \n \n Animation\n \n Choose how user messages are animated when they are added to the\n conversation.\n \n \n setMessages(initialMessages)}\n >\n \n \n \n \n \n {messages.length === 0 ? (\n \n \n \n \n \n No Messages Yet\n \n Click the button below to send the first message.\n \n \n \n ) : (\n \n \n \n \n {messages.map((message) => (\n \n ))}\n \n \n \n \n \n )}\n \n \n {\n setPresetId(value as MessageAnimationId)\n }}\n >\n \n {preset.name}\n \n \n \n {Object.values(MESSAGE_ANIMATIONS).map((animation) => (\n \n {animation.name}\n \n ))}\n \n \n \n {\n if (!nextMessage || isBusy) {\n return\n }\n\n void sendMessage(nextMessage)\n }}\n >\n \n Send Message\n \n \n \n
\n Select an animation then click send to see it in action.\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-commands.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { createChat, getMessageText } from \"@/lib/ai\"\nimport { Bubble, BubbleContent } from \"@/components/ui/bubble\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { Message, MessageContent } from \"@/components/ui/message\"\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n useMessageScroller,\n} from \"@/components/ui/message-scroller\"\n\nconst chat = createChat()\n .user(\n \"We're seeing activation dip after workspace creation. Can you help me find the likely step?\",\n { id: \"command-activation\" }\n )\n .assistant(\n \"The sharpest drop is between creating the workspace and inviting the first teammate.\\n\\nWorkspace creation is still healthy, but the invite step is where users pause. That suggests the product is asking for collaboration before the user has enough confidence in the workspace.\"\n )\n .user(\"What should I compare before we change the onboarding flow?\", {\n id: \"command-compare\",\n })\n .assistant(\n \"Compare three cohorts:\\n\\n1. Users who choose a template before inviting teammates.\\n2. Users who start from a blank workspace.\\n3. Users who skip invites and return within 24 hours.\\n\\nIf template users invite faster, the fix is probably better first-run guidance rather than a louder invite prompt.\"\n )\n .user(\"Can you turn that into an experiment?\", {\n id: \"command-experiment\",\n })\n .assistant(\n \"Yes. Create a variant that shows a short checklist after workspace creation:\\n\\n- Pick a template.\\n- Add one project detail.\\n- Invite a teammate when the workspace has context.\\n\\nMeasure first invite completion, 24-hour return rate, and whether teams create a second project.\"\n )\n .user(\"What's the risk if we delay the invite prompt?\", {\n id: \"command-risk\",\n })\n .assistant(\n \"The main risk is reducing team creation for accounts that already know who they want to invite.\\n\\nTo protect that path, keep the invite action visible in the header and only change the primary empty-state guidance. That gives confident teams a direct route without forcing uncertain users through the invite step too early.\"\n )\n\nconst messages = chat.get()\nconst userMessages = messages.filter((message) => message.role === \"user\")\n\nexport function MessageScrollerCommands() {\n return (\n \n
\n \n \n Commands\n \n Drive the transcript from outside.\n \n \n \n \n \n \n \n \n \n {messages.map((message) => {\n const isUserMessage = message.role === \"user\"\n const text = getMessageText(message)\n\n return (\n \n \n \n \n \n {text\n .split(/\\n\\s*\\n/)\n .map((paragraph) => paragraph.trim())\n .filter(Boolean)\n .map((paragraph, index) => (\n \n {paragraph}\n

\n ))}\n
\n
\n
\n
\n \n )\n })}\n
\n
\n \n
\n
\n
\n
\n Use the controls to jump to any message in the conversation.\n
\n
\n
\n )\n}\n\nfunction CommandMenu() {\n const { scrollToMessage } = useMessageScroller()\n\n return (\n \n }\n >\n Jump to...\n \n \n \n Conversations\n {userMessages.map((message) => (\n \n scrollToMessage(message.id, {\n align: \"start\",\n behavior: \"smooth\",\n })\n }\n >\n \n {getTrimmedMessageText(message)}\n \n \n ))}\n \n \n \n )\n}\n\nfunction getTrimmedMessageText(message: (typeof userMessages)[number]) {\n const text = getMessageText(message)\n\n return text.length > 42 ? `${text.slice(0, 39)}...` : text\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-demo.tsx", + "content": "\"use client\"\n\nimport { useChat } from \"@ai-sdk/react\"\nimport {\n ArrowUpIcon,\n GlobeIcon,\n ImageIcon,\n MessageCircleDashedIcon,\n PaperclipIcon,\n PlusIcon,\n RotateCwIcon,\n TelescopeIcon,\n} from \"lucide-react\"\n\nimport { createChat, getMessageText } from \"@/lib/ai\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n Empty,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/components/ui/empty\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n} from \"@/components/ui/input-group\"\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerProvider,\n MessageScrollerViewport,\n} from \"@/components/ui/message-scroller\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { MessageAnimated } from \"@/components/message-animated\"\n\nconst chat = createChat()\n .user(\n \"I'm building a chat for our app and the scroll behavior is driving me nuts. Every time the AI streams a reply, the whole thread jumps around.\"\n )\n .sleep(1000)\n .assistant(\n \"That's the classic streaming scroll problem. Wrap your message list in `MessageScroller` and turn on `autoScroll`, the viewport pins to the bottom as tokens arrive, so users always see the latest text land in place.\\n\\nThe important part: it only auto-scrolls while the reader is already at the bottom. The moment they scroll up to read something earlier, auto-scroll backs off and their position is preserved. You get smooth streaming without fighting the user's intent.\"\n )\n .user(\n \"Okay, but when someone sends a new message the view still feels jarring, like the whole conversation reloads from the top.\"\n )\n .sleep(1000)\n .assistant(\n \"MessageScrollerItem fixes that with turn anchoring. Set `scrollAnchor` on the turn that should settle near the top instead of blindly snapping to the document bottom.\\n\\nIt also leaves a small peek of the previous exchange visible above the anchor, so context isn't lost. The reply starts in view without that disorienting jump you get from a plain overflow container.\"\n )\n .user(\n \"And if they've scrolled up to re-read an older answer? I don't want to yank them back down.\"\n )\n .sleep(1000)\n .assistant(\n \"You won't. Auto-scroll only runs when the viewport is already pinned to the bottom, so scrolling up is a deliberate opt-out, their place in the thread stays put even as new tokens keep arriving below.\\n\\nWhen there is content they haven't seen yet, `MessageScrollerButton` appears at the bottom of the viewport. One tap jumps them back to the newest message and re-engages auto-scroll. Same pattern as Slack or iMessage: quiet when you're caught up, helpful when you're not.\"\n )\n .user(\"Last one, does this work with assistive tech?\")\n .sleep(1000)\n .assistant(\n '`MessageScrollerContent` sets `role=\"log\"` and `aria-relevant=\"additions\"` by default, so screen readers announce new messages as they stream in.\\n\\nThe scroll button is a real `\n

\n {rockyTurn === \"idle\"\n ? \"This will create a marker and make it the anchor\"\n : \"Now send Rocky's reply into the conversation\"}\n

\n \n \n
\n When a user joins, a marker is created. scrollAnchor on the marker\n marks it as the next turn\n
\n \n \n )\n}\n\nfunction GroupChatMessage({\n item,\n}: {\n item: Extract\n}) {\n const isCurrentUser = item.sender === currentUser\n const variant = isCurrentUser\n ? \"muted\"\n : item.role === \"assistant\"\n ? \"ghost\"\n : \"tinted\"\n\n return (\n \n \n \n {!isCurrentUser && {item.sender}}\n \n {item.text}\n \n \n \n \n )\n}\n\nfunction GroupChatMarker({\n item,\n scrollAnchor = false,\n}: {\n item: Extract\n scrollAnchor?: boolean\n}) {\n return (\n \n \n {item.text}\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-load-history.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { RotateCwIcon } from \"lucide-react\"\nimport { toast } from \"sonner\"\n\nimport { createChat, getMessageText } from \"@/lib/ai\"\nimport { Bubble, BubbleContent } from \"@/components/ui/bubble\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Marker, MarkerContent } from \"@/components/ui/marker\"\nimport { Message, MessageContent } from \"@/components/ui/message\"\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n} from \"@/components/ui/message-scroller\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\n\nconst chat = createChat()\n .user(\"Can you summarize the incident channel?\")\n .assistant(\n \"The first alert was a delayed export job. It started backing up around 09:42 UTC and triggered the warning once the retry queue crossed the threshold.\\n\\nNo customer-facing checkout paths were affected, but exports for larger workspaces were running about 12 minutes behind.\"\n )\n .user(\"Was checkout affected?\")\n .assistant(\n \"No checkout errors were reported. Payment authorization, order creation, and confirmation emails stayed inside their normal latency bands.\\n\\nThe only elevated metric was export queue depth, which maps to analytics downloads instead of checkout.\"\n )\n .user(\"What changed in the last deploy?\")\n .assistant(\n \"Only the export queue worker changed. The deploy moved large CSV jobs onto the shared retry policy, which made each failed attempt hold a worker slot longer than before.\\n\\nThe app deploy did not include checkout, pricing, or billing API changes.\"\n )\n .user(\"Do we need to roll back?\")\n .assistant(\n \"Not yet. Queue depth is recovering after we reduced retry concurrency, and the oldest pending job is now under five minutes old.\\n\\nKeep rollback ready if the queue starts climbing again, but the current trend points toward recovery.\"\n )\n .user(\"Keep watching for customer-visible issues.\")\n .assistant(\n \"I will watch the queue and support tags for another 15 minutes. I am tracking export failures, delayed download requests, and any support thread that mentions missing reports.\\n\\nIf those stay quiet through the next batch window, we can close this as an internal degradation.\"\n )\n\nconst history = chat.get()\nconst INITIAL_VISIBLE_COUNT = 5\n\nexport function MessageScrollerLoadHistory() {\n const [demoKey, setDemoKey] = React.useState(0)\n const [visibleCount, setVisibleCount] = React.useState(INITIAL_VISIBLE_COUNT)\n const visibleMessages = history.slice(-visibleCount)\n const canLoadHistory = visibleCount < history.length\n\n return (\n \n
\n \n \n Load History\n \n Prepended messages keep your place.\n \n \n \n {\n setVisibleCount(INITIAL_VISIBLE_COUNT)\n setDemoKey((key) => key + 1)\n }}\n />\n }\n >\n \n \n \n

Reset

\n
\n
\n
\n
\n \n \n \n \n {visibleMessages.map((message) => {\n const isUserMessage = message.role === \"user\"\n\n return (\n \n \n \n \n \n {getMessageText(message)\n .split(/\\n\\s*\\n/)\n .map((paragraph) => paragraph.trim())\n .filter(Boolean)\n .map((paragraph, index) => (\n \n {paragraph}\n

\n ))}\n
\n
\n
\n
\n \n )\n })}\n \n \n End of Conversation\n \n \n
\n
\n \n
\n
\n \n {\n setVisibleCount(history.length)\n toast(\"History loaded\", {\n description: \"Scroll up to see earlier messages.\",\n })\n }}\n className=\"w-full\"\n variant=\"secondary\"\n >\n {canLoadHistory ? \"Load History\" : \"History Loaded\"}\n \n

\n Restore earlier messages while keeping your place.\n

\n
\n
\n
\n Click Load History to load the entire conversation\n
\n
\n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-opening-position.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Bubble, BubbleContent } from \"@/components/ui/bubble\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Message, MessageContent } from \"@/components/ui/message\"\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n useMessageScroller,\n} from \"@/components/ui/message-scroller\"\nimport { Tabs, TabsList, TabsTrigger } from \"@/components/ui/tabs\"\n\nconst messages = [\n {\n id: \"open-1\",\n role: \"user\",\n text: \"This is the first message the user sent in the conversation.\",\n },\n {\n id: \"open-2\",\n role: \"assistant\",\n text: \"Workspace creation rose 8%, but first invite completion only rose 2%.\",\n },\n {\n id: \"open-3\",\n role: \"user\",\n text: \"This is the last message the user sent in the conversation.\",\n },\n {\n id: \"open-4\",\n role: \"assistant\",\n text: \"Start with the invite step. Teams are creating workspaces but waiting to add collaborators.\\n\\nRecommended follow-up:\\n\\n1. Compare invite drop-off by account size.\\n2. Check whether users who skip invites still return within 24 hours.\\n3. Review the empty-state copy on the first project screen.\\n4. Segment activation by template, since template users may not need invites right away.\\n\\nIf that pattern holds, the next experiment should make collaboration useful earlier instead of prompting for invites harder.\",\n },\n] satisfies Array<{\n id: string\n role: \"user\" | \"assistant\"\n text: string\n}>\n\nconst positions = [\n { value: \"start\", label: \"start\" },\n { value: \"end\", label: \"end\" },\n { value: \"last-anchor\", label: \"last-anchor\" },\n] satisfies Array<{\n value: \"start\" | \"end\" | \"last-anchor\"\n label: string\n}>\n\nexport function MessageScrollerOpeningPosition() {\n const [positionKey, setPositionKey] = React.useState(0)\n const [position, setPosition] = React.useState<\n \"start\" | \"end\" | \"last-anchor\"\n >(\"last-anchor\")\n\n return (\n
\n \n \n Opening Position\n \n Choose where a saved transcript opens.\n \n \n \n \n \n \n \n \n {\n if (\n value === \"start\" ||\n value === \"end\" ||\n value === \"last-anchor\"\n ) {\n setPosition(value)\n setPositionKey((key) => key + 1)\n }\n }}\n className=\"w-full\"\n >\n \n {positions.map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n \n
\n Toggle the defaultScrollPosition to see where the transcript starts when\n you open the thread\n
\n
\n )\n}\n\nfunction OpeningPositionScroller({\n position,\n positionKey,\n}: {\n position: \"start\" | \"end\" | \"last-anchor\"\n positionKey: number\n}) {\n const { scrollToEnd, scrollToMessage, scrollToStart } = useMessageScroller()\n\n React.useLayoutEffect(() => {\n const frame = requestAnimationFrame(() => {\n if (position === \"start\") {\n scrollToStart({ behavior: \"auto\" })\n return\n }\n\n if (position === \"end\") {\n scrollToEnd({ behavior: \"auto\" })\n return\n }\n\n scrollToMessage(\"open-3\", {\n align: \"start\",\n behavior: \"auto\",\n scrollMargin: 64,\n })\n })\n\n return () => {\n cancelAnimationFrame(frame)\n }\n }, [position, positionKey, scrollToEnd, scrollToMessage, scrollToStart])\n\n return (\n \n \n \n {messages.map((message) => {\n const isUserMessage = message.role === \"user\"\n\n return (\n \n \n \n \n \n {message.text\n .split(/\\n\\s*\\n/)\n .map((paragraph) => paragraph.trim())\n .filter(Boolean)\n .map((paragraph, index) => (\n

\n {paragraph}\n

\n ))}\n
\n
\n
\n
\n \n )\n })}\n
\n
\n \n
\n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-previous-context.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { useChat } from \"@ai-sdk/react\"\nimport {\n ArrowUpIcon,\n GlobeIcon,\n ImageIcon,\n PaperclipIcon,\n PlusIcon,\n RotateCwIcon,\n TelescopeIcon,\n} from \"lucide-react\"\n\nimport { createChat, getMessageText } from \"@/lib/ai\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n} from \"@/components/ui/input-group\"\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerProvider,\n MessageScrollerViewport,\n} from \"@/components/ui/message-scroller\"\nimport { Slider } from \"@/components/ui/slider\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { MessageAnimated } from \"@/components/message-animated\"\n\nconst DEFAULT_PEEK = 64\n\nconst chat = createChat()\n .user(\n \"I'm building a chat for our app and the scroll behavior is driving me nuts. Every time the AI streams a reply, the whole thread jumps around.\"\n )\n .sleep(1000)\n .assistant(\n \"That's the classic streaming scroll problem. Wrap your message list in `MessageScroller` and turn on `autoScroll`, the viewport pins to the bottom as tokens arrive, so users always see the latest text land in place.\\n\\nThe important part: it only auto-scrolls while the reader is already at the bottom. The moment they scroll up to read something earlier, auto-scroll backs off and their position is preserved. You get smooth streaming without fighting the user's intent.\"\n )\n .user(\n \"Okay, but when someone sends a new message the view still feels jarring, like the whole conversation reloads from the top.\"\n )\n .sleep(1000)\n .assistant(\n \"MessageScrollerItem fixes that with turn anchoring. Set `scrollAnchor` on the turn that should settle near the top instead of blindly snapping to the document bottom.\\n\\nIt also leaves a small peek of the previous exchange visible above the anchor, so context isn't lost. The reply starts in view without that disorienting jump you get from a plain overflow container.\"\n )\n .user(\n \"And if they've scrolled up to re-read an older answer? I don't want to yank them back down.\"\n )\n .sleep(1000)\n .assistant(\n \"You won't. Auto-scroll only runs when the viewport is already pinned to the bottom, so scrolling up is a deliberate opt-out, their place in the thread stays put even as new tokens keep arriving below.\\n\\nWhen there is content they haven't seen yet, `MessageScrollerButton` appears at the bottom of the viewport. One tap jumps them back to the newest message and re-engages auto-scroll. Same pattern as Slack or iMessage: quiet when you're caught up, helpful when you're not.\"\n )\n .user(\"Last one, does this work with assistive tech?\")\n .sleep(1000)\n .assistant(\n '`MessageScrollerContent` sets `role=\"log\"` and `aria-relevant=\"additions\"` by default, so screen readers announce new messages as they stream in.\\n\\nThe scroll button is a real `\n ))}\n \n \n )\n}\n\nfunction getTrimmedMessageText(message: (typeof userMessages)[number]) {\n const text = getMessageText(message)\n\n return text.length > 42 ? `${text.slice(0, 39)}...` : text\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/message-animated.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { BrainIcon } from \"lucide-react\"\nimport { motion, useReducedMotion } from \"motion/react\"\n\nimport type { MessageAnimationPreset } from \"@/lib/message-animations\"\nimport { MESSAGE_ANIMATIONS } from \"@/lib/message-animations\"\nimport { Bubble, BubbleContent } from \"@/components/ui/bubble\"\nimport { Message, MessageContent } from \"@/components/ui/message\"\nimport { MessageScrollerItem } from \"@/components/ui/message-scroller\"\n\ntype MessageAnimatedPart = {\n content?: unknown\n type: string\n text?: unknown\n}\n\ntype MessageAnimatedMessage = {\n id: string\n role: string\n text?: string\n parts?: ReadonlyArray\n}\n\nconst MotionMessageScrollerItem = motion.create(MessageScrollerItem)\n\nfunction MessageAnimated({\n message,\n animationPreset = MESSAGE_ANIMATIONS[\"slide-up\"],\n assistantVariant = \"ghost\",\n scrollAnchor,\n userVariant = \"muted\",\n ...props\n}: Omit<\n React.ComponentProps,\n \"animate\" | \"children\" | \"exit\" | \"initial\" | \"messageId\" | \"variants\"\n> & {\n animationPreset?: MessageAnimationPreset\n assistantVariant?: React.ComponentProps[\"variant\"]\n message: MessageAnimatedMessage\n userVariant?: React.ComponentProps[\"variant\"]\n}) {\n const shouldReduceMotion = useReducedMotion()\n const isUserMessage = message.role === \"user\"\n\n if (isUserMessage) {\n return (\n \n \n \n )\n }\n\n return (\n \n \n \n )\n}\n\nfunction MessageAnimatedRow({\n message,\n assistantVariant,\n userVariant,\n}: {\n assistantVariant: React.ComponentProps[\"variant\"]\n message: MessageAnimatedMessage\n userVariant: React.ComponentProps[\"variant\"]\n}) {\n const isUserMessage = message.role === \"user\"\n const parts = getMessageAnimatedContentParts(message)\n\n return (\n \n \n {parts.map((part) => {\n const paragraphs = part.text\n .split(/\\n\\s*\\n/)\n .map((paragraph) => paragraph.trim())\n .filter(Boolean)\n\n if (part.type === \"reasoning\") {\n return (\n \n
\n \n Reasoning\n
\n
\n {paragraphs.map((paragraph, paragraphIndex) => (\n \n {paragraph}\n

\n ))}\n
\n \n )\n }\n\n return (\n \n \n {paragraphs.map((paragraph, paragraphIndex) => (\n \n {paragraph}\n

\n ))}\n
\n \n )\n })}\n
\n
\n )\n}\n\nfunction getMessageAnimatedContentParts(message: MessageAnimatedMessage) {\n if (message.parts) {\n return message.parts.flatMap((part, index) => {\n const type =\n part.type === \"reasoning\" || part.type === \"thinking\"\n ? \"reasoning\"\n : part.type === \"text\"\n ? \"text\"\n : null\n const text =\n typeof part.text === \"string\"\n ? part.text\n : typeof part.content === \"string\"\n ? part.content\n : null\n\n if (!type || text === null) {\n return []\n }\n\n return [\n {\n key: `${message.id}-${index}`,\n text,\n type,\n },\n ]\n })\n }\n\n return typeof message.text === \"string\"\n ? [{ key: `${message.id}-text`, text: message.text, type: \"text\" }]\n : []\n}\n\nexport { MessageAnimated, type MessageAnimatedMessage }\n", + "type": "registry:component" + }, + { + "path": "src/lib/ai.ts", + "content": "import type { UIMessage } from \"ai\"\n\n// Compatibility bridge for v4 examples that still import from `@/lib/ai`.\n// The public chat API lives in `@shadcn/helpers/ai-sdk`; `getMessageText`\n// remains local to the app.\n\nexport * from \"@shadcn/helpers/ai-sdk\"\n\nexport function getMessageText(message: Pick) {\n return message.parts.reduce(\n (text, part) => (part.type === \"text\" ? text + part.text : text),\n \"\"\n )\n}\n", + "type": "registry:lib" + }, + { + "path": "src/lib/message-animations.ts", + "content": "import type { Variants } from \"motion/react\"\n\nconst ANIMATIONS = [\n {\n id: \"fade\",\n name: \"Fade\",\n variants: {\n initial: { opacity: 0 },\n animate: {\n opacity: 1,\n transition: { duration: 0.22, ease: \"easeOut\" },\n },\n exit: { opacity: 0, transition: { duration: 0.15 } },\n },\n },\n {\n id: \"slide-up\",\n name: \"Slide Up\",\n variants: {\n initial: { opacity: 0, y: 10 },\n animate: {\n opacity: 1,\n y: 0,\n transition: { duration: 0.26, ease: [0.16, 1, 0.3, 1] },\n },\n exit: { opacity: 0, y: 4, transition: { duration: 0.15 } },\n },\n },\n {\n id: \"slide-side\",\n name: \"Slide Side\",\n variants: {\n initial: { opacity: 0, x: 18 },\n animate: {\n opacity: 1,\n x: 0,\n transition: { duration: 0.28, ease: [0.16, 1, 0.3, 1] },\n },\n exit: {\n opacity: 0,\n x: 8,\n transition: { duration: 0.15 },\n },\n },\n },\n {\n id: \"pop\",\n name: \"Pop\",\n variants: {\n initial: {\n opacity: 0,\n scale: 0.94,\n y: 6,\n originX: 1,\n originY: 1,\n },\n animate: {\n opacity: 1,\n y: 0,\n scale: 1,\n transition: { type: \"spring\", stiffness: 500, damping: 34, mass: 0.7 },\n },\n exit: { opacity: 0, scale: 0.98, transition: { duration: 0.12 } },\n },\n },\n {\n id: \"spring-bounce\",\n name: \"Spring Bounce\",\n variants: {\n initial: { opacity: 0, y: 12, scale: 0.96 },\n animate: {\n opacity: 1,\n y: 0,\n scale: 1,\n transition: {\n type: \"spring\",\n stiffness: 520,\n damping: 30,\n mass: 0.7,\n },\n },\n exit: { opacity: 0, scale: 0.98, transition: { duration: 0.12 } },\n },\n },\n {\n id: \"blur-fade\",\n name: \"Blur Fade\",\n variants: {\n initial: { opacity: 0, filter: \"blur(4px)\", y: 6 },\n animate: {\n opacity: 1,\n y: 0,\n filter: \"blur(0px)\",\n transition: { duration: 0.28, ease: \"easeOut\" },\n },\n exit: {\n opacity: 0,\n filter: \"blur(2px)\",\n transition: { duration: 0.15 },\n },\n },\n },\n {\n id: \"scale-fade\",\n name: \"Scale Fade\",\n variants: {\n initial: { opacity: 0, scale: 0.98 },\n animate: {\n opacity: 1,\n scale: 1,\n transition: { duration: 0.24, ease: \"easeOut\" },\n },\n exit: { opacity: 0, scale: 0.99, transition: { duration: 0.12 } },\n },\n },\n] as const satisfies {\n id: string\n name: string\n variants: Variants\n}[]\n\ntype MessageAnimationPreset = (typeof ANIMATIONS)[number]\ntype MessageAnimationId = MessageAnimationPreset[\"id\"]\n\nconst MESSAGE_ANIMATIONS = ANIMATIONS.reduce(\n (acc, preset) => {\n acc[preset.id] = preset\n return acc\n },\n {} as Record\n)\n\nexport {\n MESSAGE_ANIMATIONS,\n type MessageAnimationId,\n type MessageAnimationPreset,\n}\n", + "type": "registry:lib" + } + ], + "docs": "https://ui.full.dev/react/components/message-scroller/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/message-scroller.json b/public/r/react/styles/base-luma/message-scroller.json new file mode 100644 index 000000000..98fb53f23 --- /dev/null +++ b/public/r/react/styles/base-luma/message-scroller.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "message-scroller", + "title": "Message Scroller", + "description": "Scrolls a conversation and keeps the latest message in view.", + "dependencies": [ + "@shadcn/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/message-scroller.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n MessageScroller as MessageScrollerPrimitive,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n} from \"@shadcn/react/message-scroller\"\nimport { cn } from \"cn\"\nimport { ArrowDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nfunction MessageScrollerProvider(\n props: React.ComponentProps\n) {\n return \n}\n\nfunction MessageScroller({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction MessageScrollerViewport({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction MessageScrollerContent({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction MessageScrollerItem({\n className,\n scrollAnchor = false,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction MessageScrollerButton({\n direction = \"end\",\n className,\n children,\n render,\n variant = \"secondary\",\n size = \"icon-sm\",\n ...props\n}: React.ComponentProps &\n Pick, \"variant\" | \"size\">) {\n return (\n }\n {...props}\n >\n {children ?? (\n <>\n \n \n {direction === \"end\" ? \"Scroll to end\" : \"Scroll to start\"}\n \n \n )}\n \n )\n}\n\nexport {\n MessageScrollerProvider,\n MessageScroller,\n MessageScrollerViewport,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerButton,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/message-scroller/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/message.json b/public/r/react/styles/base-luma/message.json new file mode 100644 index 000000000..6f2b440b7 --- /dev/null +++ b/public/r/react/styles/base-luma/message.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "message", + "title": "Message", + "description": "A chat message with avatar, header, content and footer.", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/message.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nfunction MessageGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction Message({\n className,\n align = \"start\",\n ...props\n}: React.ComponentProps<\"div\"> & { align?: \"start\" | \"end\" }) {\n return (\n \n )\n}\n\nfunction MessageAvatar({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction MessageContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction MessageHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction MessageFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nexport {\n MessageGroup,\n Message,\n MessageAvatar,\n MessageContent,\n MessageFooter,\n MessageHeader,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/message/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/native-select-examples.json b/public/r/react/styles/base-luma/native-select-examples.json new file mode 100644 index 000000000..41255f389 --- /dev/null +++ b/public/r/react/styles/base-luma/native-select-examples.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "native-select-examples", + "title": "Native Select examples", + "description": "The examples from the shadcn/ui Native Select docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/native-select", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/native-select/native-select-demo.tsx", + "content": "import { NativeSelect, NativeSelectOption } from \"@/components/ui/native-select\"\n\nexport function NativeSelectDemo() {\n return (\n \n Select status\n Todo\n In Progress\n Done\n Cancelled\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-disabled.tsx", + "content": "import { NativeSelect, NativeSelectOption } from \"@/components/ui/native-select\"\n\nexport function NativeSelectDisabled() {\n return (\n \n Disabled\n Apple\n Banana\n Blueberry\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-groups.tsx", + "content": "import {\n NativeSelect,\n NativeSelectOptGroup,\n NativeSelectOption,\n} from \"@/components/ui/native-select\"\n\nexport function NativeSelectGroups() {\n return (\n \n Select department\n \n Frontend\n Backend\n DevOps\n \n \n Sales Rep\n \n Account Manager\n \n \n Sales Director\n \n \n \n \n Customer Support\n \n \n Product Manager\n \n \n Operations Manager\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-invalid.tsx", + "content": "import { NativeSelect, NativeSelectOption } from \"@/components/ui/native-select\"\n\nexport function NativeSelectInvalid() {\n return (\n \n Error state\n Apple\n Banana\n Blueberry\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { NativeSelect, NativeSelectOption } from \"@/components/ui/native-select\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n placeholder: \"Select status\",\n todo: \"Todo\",\n inProgress: \"In Progress\",\n done: \"Done\",\n cancelled: \"Cancelled\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n placeholder: \"اختر الحالة\",\n todo: \"مهام\",\n inProgress: \"قيد التنفيذ\",\n done: \"منجز\",\n cancelled: \"ملغي\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n placeholder: \"בחר סטטוס\",\n todo: \"לעשות\",\n inProgress: \"בתהליך\",\n done: \"הושלם\",\n cancelled: \"בוטל\",\n },\n },\n}\n\nexport function NativeSelectRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n \n {t.placeholder}\n {t.todo}\n \n {t.inProgress}\n \n {t.done}\n {t.cancelled}\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/native-select/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/native-select.json b/public/r/react/styles/base-luma/native-select.json new file mode 100644 index 000000000..752830ac8 --- /dev/null +++ b/public/r/react/styles/base-luma/native-select.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "native-select", + "title": "Native Select", + "description": "A styled native HTML select element with consistent design system integration.", + "dependencies": [ + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/native-select.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\ntype NativeSelectProps = Omit, \"size\"> & {\n size?: \"sm\" | \"default\"\n}\n\nfunction NativeSelect({\n className,\n size = \"default\",\n ...props\n}: NativeSelectProps) {\n return (\n \n \n \n \n )\n}\n\nfunction NativeSelectOption({\n className,\n ...props\n}: React.ComponentProps<\"option\">) {\n return (\n \n )\n}\n\nfunction NativeSelectOptGroup({\n className,\n ...props\n}: React.ComponentProps<\"optgroup\">) {\n return (\n \n )\n}\n\nexport { NativeSelect, NativeSelectOptGroup, NativeSelectOption }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/native-select/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/navigation-menu-examples.json b/public/r/react/styles/base-luma/navigation-menu-examples.json new file mode 100644 index 000000000..c105eab85 --- /dev/null +++ b/public/r/react/styles/base-luma/navigation-menu-examples.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "navigation-menu-examples", + "title": "Navigation Menu examples", + "description": "The examples from the shadcn/ui Navigation Menu docs.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/navigation-menu", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/navigation-menu/navigation-menu-demo.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n CircleAlertIcon,\n CircleCheckIcon,\n CircleDashedIcon,\n} from \"lucide-react\"\n\nimport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n} from \"@/components/ui/navigation-menu\"\n\nconst components: { title: string; href: string; description: string }[] = [\n {\n title: \"Alert Dialog\",\n href: \"https://ui.shadcn.com/docs/components/base/alert-dialog\",\n description:\n \"A modal dialog that interrupts the user with important content and expects a response.\",\n },\n {\n title: \"Hover Card\",\n href: \"https://ui.shadcn.com/docs/components/base/hover-card\",\n description:\n \"For sighted users to preview content available behind a link.\",\n },\n {\n title: \"Progress\",\n href: \"https://ui.shadcn.com/docs/components/base/progress\",\n description:\n \"Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.\",\n },\n {\n title: \"Scroll-area\",\n href: \"https://ui.shadcn.com/docs/components/base/scroll-area\",\n description: \"Visually or semantically separates content.\",\n },\n {\n title: \"Tabs\",\n href: \"https://ui.shadcn.com/docs/components/base/tabs\",\n description:\n \"A set of layered sections of content, known as tab panels, that are displayed one at a time.\",\n },\n {\n title: \"Tooltip\",\n href: \"https://ui.shadcn.com/docs/components/base/tooltip\",\n description:\n \"A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.\",\n },\n]\n\nexport function NavigationMenuDemo() {\n return (\n \n \n \n Getting started\n \n
    \n \n Re-usable components built with Tailwind CSS.\n \n \n How to install dependencies and structure your app.\n \n \n Styles for headings, paragraphs, lists...etc\n \n
\n
\n
\n \n Components\n \n
    \n {components.map((component) => (\n \n {component.description}\n \n ))}\n
\n
\n
\n \n With Icon\n \n
    \n
  • \n \n }\n >\n \n Backlog\n \n \n }\n >\n \n To Do\n \n \n }\n >\n \n Done\n \n
  • \n
\n
\n
\n \n }\n className={navigationMenuTriggerStyle()}\n >\n Docs\n \n \n
\n
\n )\n}\n\nfunction ListItem({\n title,\n children,\n href,\n ...props\n}: React.ComponentPropsWithoutRef<\"li\"> & { href: string }) {\n return (\n
  • \n }>\n
    \n
    {title}
    \n
    {children}
    \n
    \n
    \n
  • \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/navigation-menu/navigation-menu-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n CircleAlertIcon,\n CircleCheckIcon,\n CircleDashedIcon,\n} from \"lucide-react\"\n\nimport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n} from \"@/components/ui/navigation-menu\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n gettingStarted: \"Getting started\",\n introduction: \"Introduction\",\n introductionDesc: \"Re-usable components built with Tailwind CSS.\",\n installation: \"Installation\",\n installationDesc: \"How to install dependencies and structure your app.\",\n typography: \"Typography\",\n typographyDesc: \"Styles for headings, paragraphs, lists...etc\",\n components: \"Components\",\n alertDialog: \"Alert Dialog\",\n alertDialogDesc:\n \"A modal dialog that interrupts the user with important content and expects a response.\",\n hoverCard: \"Hover Card\",\n hoverCardDesc:\n \"For sighted users to preview content available behind a link.\",\n progress: \"Progress\",\n progressDesc:\n \"Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.\",\n scrollArea: \"Scroll-area\",\n scrollAreaDesc: \"Visually or semantically separates content.\",\n tabs: \"Tabs\",\n tabsDesc:\n \"A set of layered sections of content, known as tab panels, that are displayed one at a time.\",\n tooltip: \"Tooltip\",\n tooltipDesc:\n \"A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.\",\n withIcon: \"With Icon\",\n backlog: \"Backlog\",\n toDo: \"To Do\",\n done: \"Done\",\n docs: \"Docs\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n gettingStarted: \"البدء\",\n introduction: \"مقدمة\",\n introductionDesc:\n \"مكونات قابلة لإعادة الاستخدام مبنية باستخدام Tailwind CSS.\",\n installation: \"التثبيت\",\n installationDesc: \"كيفية تثبيت التبعيات وتنظيم تطبيقك.\",\n typography: \"الطباعة\",\n typographyDesc: \"أنماط للعناوين والفقرات والقوائم...إلخ\",\n components: \"المكونات\",\n alertDialog: \"حوار التنبيه\",\n alertDialogDesc: \"حوار نافذة يقطع المستخدم بمحتوى مهم ويتوقع استجابة.\",\n hoverCard: \"بطاقة التحويم\",\n hoverCardDesc: \"للمستخدمين المبصرين لمعاينة المحتوى المتاح خلف الرابط.\",\n progress: \"التقدم\",\n progressDesc:\n \"يعرض مؤشرًا يوضح تقدم إتمام المهمة، عادةً يتم عرضه كشريط تقدم.\",\n scrollArea: \"منطقة التمرير\",\n scrollAreaDesc: \"يفصل المحتوى بصريًا أو دلاليًا.\",\n tabs: \"التبويبات\",\n tabsDesc:\n \"مجموعة من أقسام المحتوى المتعددة الطبقات، المعروفة بألواح التبويب، التي يتم عرضها واحدة في كل مرة.\",\n tooltip: \"تلميح\",\n tooltipDesc:\n \"نافذة منبثقة تعرض معلومات متعلقة بعنصر عندما يتلقى العنصر التركيز على لوحة المفاتيح أو عند تحويم الماوس فوقه.\",\n withIcon: \"مع أيقونة\",\n backlog: \"قائمة الانتظار\",\n toDo: \"المهام\",\n done: \"منجز\",\n docs: \"الوثائق\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n gettingStarted: \"התחלה\",\n introduction: \"הקדמה\",\n introductionDesc: \"רכיבים לשימוש חוזר שנבנו עם Tailwind CSS.\",\n installation: \"התקנה\",\n installationDesc: \"כיצד להתקין תלויות ולבנות את האפליקציה שלך.\",\n typography: \"טיפוגרפיה\",\n typographyDesc: \"סגנונות לכותרות, פסקאות, רשימות...וכו'\",\n components: \"רכיבים\",\n alertDialog: \"דיאלוג התראה\",\n alertDialogDesc: \"דיאלוג מודאלי שמפריע למשתמש עם תוכן חשוב ומצפה לתגובה.\",\n hoverCard: \"כרטיס ריחוף\",\n hoverCardDesc:\n \"למשתמשים רואים כדי להציג תצוגה מקדימה של תוכן זמין מאחורי קישור.\",\n progress: \"התקדמות\",\n progressDesc:\n \"מציג אינדיקטור המציג את התקדמות ההשלמה של משימה, בדרך כלל מוצג כסרגל התקדמות.\",\n scrollArea: \"אזור גלילה\",\n scrollAreaDesc: \"מפריד תוכן חזותית או סמנטית.\",\n tabs: \"כרטיסיות\",\n tabsDesc:\n \"קבוצה של חלקי תוכן מרובדים, המכונים לוחות כרטיסיות, המוצגים אחד בכל פעם.\",\n tooltip: \"טולטיפ\",\n tooltipDesc:\n \"חלון קופץ המציג מידע הקשור לאלמנט כאשר האלמנט מקבל מיקוד מקלדת או כאשר העכבר מרחף מעליו.\",\n withIcon: \"עם אייקון\",\n backlog: \"רשימת המתנה\",\n toDo: \"לעשות\",\n done: \"הושלם\",\n docs: \"תיעוד\",\n },\n },\n}\n\nconst components = [\n {\n titleKey: \"alertDialog\" as const,\n descriptionKey: \"alertDialogDesc\" as const,\n href: \"https://ui.shadcn.com/docs/components/base/alert-dialog\",\n },\n {\n titleKey: \"hoverCard\" as const,\n descriptionKey: \"hoverCardDesc\" as const,\n href: \"https://ui.shadcn.com/docs/components/base/hover-card\",\n },\n {\n titleKey: \"progress\" as const,\n descriptionKey: \"progressDesc\" as const,\n href: \"https://ui.shadcn.com/docs/components/base/progress\",\n },\n {\n titleKey: \"scrollArea\" as const,\n descriptionKey: \"scrollAreaDesc\" as const,\n href: \"https://ui.shadcn.com/docs/components/base/scroll-area\",\n },\n {\n titleKey: \"tabs\" as const,\n descriptionKey: \"tabsDesc\" as const,\n href: \"https://ui.shadcn.com/docs/components/base/tabs\",\n },\n {\n titleKey: \"tooltip\" as const,\n descriptionKey: \"tooltipDesc\" as const,\n href: \"https://ui.shadcn.com/docs/components/base/tooltip\",\n },\n] as const\n\nexport function NavigationMenuRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n\n return (\n \n \n \n {t.gettingStarted}\n \n
      \n \n {t.introductionDesc}\n \n \n {t.installationDesc}\n \n \n {t.typographyDesc}\n \n
    \n \n
    \n \n {t.components}\n \n
      \n {components.map((component) => (\n \n {t[component.descriptionKey]}\n \n ))}\n
    \n \n
    \n \n {t.withIcon}\n \n
      \n
    • \n \n }\n >\n \n {t.backlog}\n \n \n }\n >\n \n {t.toDo}\n \n \n }\n >\n \n {t.done}\n \n
    • \n
    \n \n
    \n \n }\n className={navigationMenuTriggerStyle()}\n data-lang={dir === \"rtl\" ? language : undefined}\n >\n {t.docs}\n \n \n
    \n
    \n )\n}\n\nfunction ListItem({\n title,\n children,\n href,\n ...props\n}: React.ComponentPropsWithoutRef<\"li\"> & { href: string }) {\n return (\n
  • \n }>\n
    \n
    {title}
    \n
    {children}
    \n
    \n
    \n
  • \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/navigation-menu/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/navigation-menu.json b/public/r/react/styles/base-luma/navigation-menu.json new file mode 100644 index 000000000..f26acbeda --- /dev/null +++ b/public/r/react/styles/base-luma/navigation-menu.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "navigation-menu", + "title": "Navigation Menu", + "description": "A collection of links for navigating websites.", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/navigation-menu.tsx", + "content": "import { NavigationMenu as NavigationMenuPrimitive } from \"@base-ui/react/navigation-menu\"\nimport { cva } from \"class-variance-authority\"\nimport { cn } from \"cn\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nfunction NavigationMenu({\n align = \"start\",\n className,\n children,\n ...props\n}: NavigationMenuPrimitive.Root.Props &\n Pick) {\n return (\n \n {children}\n \n \n )\n}\n\nfunction NavigationMenuList({\n className,\n ...props\n}: React.ComponentPropsWithRef) {\n return (\n \n )\n}\n\nfunction NavigationMenuItem({\n className,\n ...props\n}: React.ComponentPropsWithRef) {\n return (\n \n )\n}\n\nconst navigationMenuTriggerStyle = cva(\n \"hover:bg-muted focus:bg-muted data-open:hover:bg-muted data-open:focus:bg-muted data-open:bg-muted/50 focus-visible:ring-ring/30 data-popup-open:bg-muted/50 data-popup-open:hover:bg-muted rounded-3xl px-4.5 py-2.5 text-sm font-medium transition-all focus-visible:ring-3 focus-visible:outline-1 disabled:opacity-50 group/navigation-menu-trigger inline-flex h-9 w-max items-center justify-center outline-none disabled:pointer-events-none\"\n)\n\nfunction NavigationMenuTrigger({\n className,\n children,\n ...props\n}: NavigationMenuPrimitive.Trigger.Props) {\n return (\n \n {children}{\" \"}\n \n \n )\n}\n\nfunction NavigationMenuContent({\n className,\n ...props\n}: NavigationMenuPrimitive.Content.Props) {\n return (\n \n )\n}\n\nfunction NavigationMenuPositioner({\n className,\n side = \"bottom\",\n sideOffset = 8,\n align = \"start\",\n alignOffset = 0,\n ...props\n}: NavigationMenuPrimitive.Positioner.Props) {\n return (\n \n \n \n \n \n \n \n )\n}\n\nfunction NavigationMenuLink({\n className,\n ...props\n}: NavigationMenuPrimitive.Link.Props) {\n return (\n \n )\n}\n\nfunction NavigationMenuIndicator({\n className,\n ...props\n}: React.ComponentPropsWithRef) {\n return (\n \n
    \n \n )\n}\n\nexport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuIndicator,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n NavigationMenuPositioner,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/navigation-menu/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/pagination-examples.json b/public/r/react/styles/base-luma/pagination-examples.json new file mode 100644 index 000000000..c5238191c --- /dev/null +++ b/public/r/react/styles/base-luma/pagination-examples.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "pagination-examples", + "title": "Pagination examples", + "description": "The examples from the shadcn/ui Pagination docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/field", + "@fulldev/pagination", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/pagination/pagination-demo.tsx", + "content": "import {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n} from \"@/components/ui/pagination\"\n\nexport function PaginationDemo() {\n return (\n \n \n \n \n \n \n 1\n \n \n \n 2\n \n \n \n 3\n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/pagination/pagination-icons-only.tsx", + "content": "import { Field, FieldLabel } from \"@/components/ui/field\"\nimport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationNext,\n PaginationPrevious,\n} from \"@/components/ui/pagination\"\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport function PaginationIconsOnly() {\n return (\n
    \n \n Rows per page\n \n \n \n \n \n \n \n \n \n \n \n \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/pagination/pagination-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n} from \"@/components/ui/pagination\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n previous: \"Previous\",\n next: \"Next\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n previous: \"السابق\",\n next: \"التالي\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n previous: \"הקודם\",\n next: \"הבא\",\n },\n },\n}\n\nfunction toArabicNumerals(num: number): string {\n const arabicNumerals = [\"٠\", \"١\", \"٢\", \"٣\", \"٤\", \"٥\", \"٦\", \"٧\", \"٨\", \"٩\"]\n return num\n .toString()\n .split(\"\")\n .map((digit) => arabicNumerals[parseInt(digit, 10)])\n .join(\"\")\n}\n\nexport function PaginationRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n\n const formatNumber = (num: number): string => {\n if (language === \"ar\") {\n return toArabicNumerals(num)\n }\n return num.toString()\n }\n\n return (\n \n \n \n \n \n \n {formatNumber(1)}\n \n \n \n {formatNumber(2)}\n \n \n \n {formatNumber(3)}\n \n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/pagination/pagination-simple.tsx", + "content": "import {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n} from \"@/components/ui/pagination\"\n\nexport function PaginationSimple() {\n return (\n \n \n \n 1\n \n \n \n 2\n \n \n \n 3\n \n \n 4\n \n \n 5\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/pagination/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/pagination.json b/public/r/react/styles/base-luma/pagination.json new file mode 100644 index 000000000..e08d8d1cc --- /dev/null +++ b/public/r/react/styles/base-luma/pagination.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "pagination", + "title": "Pagination", + "description": "Page navigation with previous, next, numbered, and overflow links.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/pagination.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n MoreHorizontalIcon,\n} from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nfunction Pagination({ className, ...props }: React.ComponentProps<\"nav\">) {\n return (\n \n )\n}\n\nfunction PaginationContent({\n className,\n ...props\n}: React.ComponentProps<\"ul\">) {\n return (\n \n )\n}\n\nfunction PaginationItem({ ...props }: React.ComponentProps<\"li\">) {\n return
  • \n}\n\ntype PaginationLinkProps = {\n isActive?: boolean\n} & Pick, \"size\"> &\n React.ComponentProps<\"a\">\n\nfunction PaginationLink({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) {\n return (\n \n }\n />\n )\n}\n\nfunction PaginationPrevious({\n className,\n text = \"Previous\",\n ...props\n}: React.ComponentProps & { text?: string }) {\n return (\n \n \n {text}\n \n )\n}\n\nfunction PaginationNext({\n className,\n text = \"Next\",\n ...props\n}: React.ComponentProps & { text?: string }) {\n return (\n \n {text}\n \n \n )\n}\n\nfunction PaginationEllipsis({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n \n \n More pages\n \n )\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/pagination/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/popover-examples.json b/public/r/react/styles/base-luma/popover-examples.json new file mode 100644 index 000000000..cdf05cdc0 --- /dev/null +++ b/public/r/react/styles/base-luma/popover-examples.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "popover-examples", + "title": "Popover examples", + "description": "The examples from the shadcn/ui Popover docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/field", + "@fulldev/input", + "@fulldev/label", + "@fulldev/popover", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/popover/popover-alignments.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n\nexport function PopoverAlignments() {\n return (\n <>\n
    \n \n }>\n Start\n \n \n Aligned to start\n \n \n \n }>\n Center\n \n \n Aligned to center\n \n \n \n }>\n End\n \n \n Aligned to end\n \n \n
    \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-basic.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n\nexport function PopoverBasic() {\n return (\n <>\n \n }>\n Open Popover\n \n \n \n Dimensions\n \n Set the dimensions for the layer.\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-demo.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport { Label } from \"@/components/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n\nexport function PopoverDemo() {\n return (\n \n }>\n Open popover\n \n \n
    \n
    \n

    Dimensions

    \n

    \n Set the dimensions for the layer.\n

    \n
    \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n
    \n
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-form.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\n\nexport function PopoverForm() {\n return (\n <>\n \n }>\n Open Popover\n \n \n \n Dimensions\n \n Set the dimensions for the layer.\n \n \n \n \n \n Width\n \n \n \n \n \n Height\n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-rtl.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n} from \"@/components/ui/popover\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n title: \"Dimensions\",\n description: \"Set the dimensions for the layer.\",\n \"inline-start\": \"Inline Start\",\n left: \"Left\",\n top: \"Top\",\n bottom: \"Bottom\",\n right: \"Right\",\n \"inline-end\": \"Inline End\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n title: \"الأبعاد\",\n description: \"تعيين الأبعاد للطبقة.\",\n \"inline-start\": \"بداية السطر\",\n left: \"يسار\",\n top: \"أعلى\",\n bottom: \"أسفل\",\n right: \"يمين\",\n \"inline-end\": \"نهاية السطر\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n title: \"מימדים\",\n description: \"הגדר את המימדים לשכבה.\",\n \"inline-start\": \"תחילת השורה\",\n left: \"שמאל\",\n top: \"למעלה\",\n bottom: \"למטה\",\n right: \"ימין\",\n \"inline-end\": \"סוף השורה\",\n },\n },\n}\n\nconst physicalSides = [\"left\", \"top\", \"bottom\", \"right\"] as const\nconst logicalSides = [\"inline-start\", \"inline-end\"] as const\n\nexport function PopoverRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n
    \n
    \n {physicalSides.map((side) => (\n \n }>\n {t[side]}\n \n \n \n {t.title}\n {t.description}\n \n \n \n ))}\n
    \n
    \n {logicalSides.map((side) => (\n \n }>\n {t[side]}\n \n \n \n {t.title}\n {t.description}\n \n \n \n ))}\n
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/popover/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/popover.json b/public/r/react/styles/base-luma/popover.json new file mode 100644 index 000000000..6772a0146 --- /dev/null +++ b/public/r/react/styles/base-luma/popover.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "popover", + "title": "Popover", + "description": "Displays rich content in a floating layer, triggered by a button.", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/popover.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Popover as PopoverPrimitive } from \"@base-ui/react/popover\"\nimport { cn } from \"cn\"\n\nfunction Popover({ ...props }: PopoverPrimitive.Root.Props) {\n return \n}\n\nfunction PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {\n return \n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n alignOffset = 0,\n side = \"bottom\",\n sideOffset = 4,\n ...props\n}: PopoverPrimitive.Popup.Props &\n Pick<\n PopoverPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n \n \n \n \n \n )\n}\n\nfunction PopoverHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {\n return (\n \n )\n}\n\nfunction PopoverDescription({\n className,\n ...props\n}: PopoverPrimitive.Description.Props) {\n return (\n \n )\n}\n\nexport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/popover/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/price.json b/public/r/react/styles/base-luma/price.json new file mode 100644 index 000000000..f5a3ae0cc --- /dev/null +++ b/public/r/react/styles/base-luma/price.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "price", + "title": "Price", + "description": "A flexible price display component for showing pricing information.", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/price.tsx", + "content": "import * as React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\ninterface FormatPriceValueOptions {\n currency: string\n locale: string\n}\n\ntype PriceValue = number | string | [number, number]\ntype DiscountFormat = \"percentage\" | \"amount\"\n\nfunction formatCurrency(value: number, options: FormatPriceValueOptions) {\n return new Intl.NumberFormat(options.locale, {\n style: \"currency\",\n currency: options.currency,\n }).format(value)\n}\n\nfunction parseSinglePriceValue(price: PriceValue | null | undefined) {\n if (price === null || price === undefined || price === \"\") {\n return null\n }\n\n if (typeof price === \"number\") {\n return Number.isFinite(price) ? price : null\n }\n\n if (Array.isArray(price)) {\n return null\n }\n\n const numericValue = Number(price)\n\n if (!Number.isNaN(numericValue) && Number.isFinite(numericValue)) {\n return numericValue\n }\n\n return null\n}\n\nfunction formatPriceDiscount(\n price: PriceValue | null | undefined,\n compareAt: PriceValue | null | undefined,\n options: FormatPriceValueOptions & {\n format?: DiscountFormat\n }\n) {\n const currentPrice = parseSinglePriceValue(price)\n const originalPrice = parseSinglePriceValue(compareAt)\n\n if (\n currentPrice === null ||\n originalPrice === null ||\n originalPrice <= currentPrice ||\n originalPrice <= 0\n ) {\n return null\n }\n\n if (options.format === \"amount\") {\n return formatCurrency(originalPrice - currentPrice, options)\n }\n\n return `${Math.round(((originalPrice - currentPrice) / originalPrice) * 100)}%`\n}\n\nfunction formatPriceValue(\n price: PriceValue | null | undefined,\n options: FormatPriceValueOptions\n) {\n if (price === null || price === undefined || price === \"\") {\n return null\n }\n\n if (typeof price === \"number\") {\n return formatCurrency(price, options)\n }\n\n if (Array.isArray(price)) {\n const [minimum, maximum] = price\n return `${formatCurrency(minimum, options)} - ${formatCurrency(maximum, options)}`\n }\n\n const rangeMatch = price.match(\n /^\\s*(-?\\d+(?:\\.\\d+)?)\\s*-\\s*(-?\\d+(?:\\.\\d+)?)\\s*$/\n )\n\n if (!rangeMatch) {\n return price\n }\n\n const [, minimum, maximum] = rangeMatch\n return `${formatCurrency(Number(minimum), options)} - ${formatCurrency(Number(maximum), options)}`\n}\n\nfunction Price({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nconst priceValueVariants = cva(\"leading-tight\", {\n variants: {\n variant: {\n default: \"text-foreground\",\n sale: \"text-muted-foreground line-through\",\n },\n },\n})\n\nfunction PriceValue({\n className,\n price,\n compareAt,\n currency = \"USD\",\n locale = \"en-US\",\n variant = \"default\",\n discountFormat = \"percentage\",\n showDiscount = true,\n discountLabel = \"Save\",\n ...props\n}: React.ComponentProps<\"span\"> & {\n price?: PriceValue\n compareAt?: PriceValue\n currency?: string\n locale?: string\n variant?: \"default\" | \"sale\"\n discountFormat?: DiscountFormat\n showDiscount?: boolean\n discountLabel?: string\n}) {\n const formattedPrice = formatPriceValue(price, { currency, locale })\n if (formattedPrice === null) return null\n const currentValue = parseSinglePriceValue(price)\n const compareAtValue = parseSinglePriceValue(compareAt)\n // A compare-at price only shows when it is higher than the price.\n const formattedCompareAt =\n currentValue !== null &&\n compareAtValue !== null &&\n compareAtValue <= currentValue\n ? null\n : formatPriceValue(compareAt, { currency, locale })\n const formattedDiscount =\n showDiscount && formattedCompareAt !== null\n ? formatPriceDiscount(price, compareAt, {\n currency,\n locale,\n format: discountFormat,\n })\n : null\n\n return (\n \n {formattedPrice}\n {formattedCompareAt !== null && (\n \n {formattedCompareAt}\n \n )}\n {formattedDiscount !== null && (\n \n {discountLabel} {formattedDiscount}\n \n )}\n \n )\n}\n\nfunction PriceUnit({\n className,\n children,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n \n / {children}\n \n )\n}\n\nexport { Price, PriceUnit, PriceValue }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/price/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/pricing-1.json b/public/r/react/styles/base-luma/pricing-1.json new file mode 100644 index 000000000..b38900986 --- /dev/null +++ b/public/r/react/styles/base-luma/pricing-1.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "pricing-1", + "title": "Pricing 1", + "description": "Pricing sections for plan grids, featured offers, and concise offer presentation.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/pricing-1.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Price, PriceUnit, PriceValue } from \"@/components/ui/price\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction Pricing1({\n title,\n description,\n featuredLabel,\n locale,\n discountLabel,\n plans,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n featuredLabel: string\n locale?: string\n discountLabel?: string\n plans: {\n name: string\n description: string\n price: {\n value: number\n compareAt?: number\n currency: string\n unit: string\n }\n featured?: boolean\n features: string[]\n button: {\n label: string\n href: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n {title}\n {description}\n
    \n
    \n \n
    \n {plans.map((plan) => (\n \n \n
    \n \n

    {plan.name}

    \n
    \n {plan.featured && {featuredLabel}}\n
    \n {plan.description}\n
    \n \n \n \n {plan.price.unit}\n \n \n
      \n {plan.features.map((feature) => (\n \n \n {feature}\n \n ))}\n
    \n
    \n \n \n {plan.button.label}\n \n \n \n ))}\n
    \n
    \n
    \n )\n}\n\nexport { Pricing1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/pricing/", + "categories": [ + "pricing" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/pricing-2.json b/public/r/react/styles/base-luma/pricing-2.json new file mode 100644 index 000000000..740290a4c --- /dev/null +++ b/public/r/react/styles/base-luma/pricing-2.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "pricing-2", + "title": "Pricing 2", + "description": "Pricing sections for plan grids, featured offers, and concise offer presentation.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/pricing-2.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Price, PriceUnit, PriceValue } from \"@/components/ui/price\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction Pricing2({\n title,\n description,\n locale,\n discountLabel,\n plans,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n locale?: string\n discountLabel?: string\n plans: {\n name: string\n description: string\n price: {\n value: number\n compareAt?: number\n currency: string\n unit: string\n }\n featured?: boolean\n features: string[]\n button: {\n label: string\n href: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n {title}\n \n {description}\n \n
    \n
    \n {plans.map((plan) => (\n \n \n \n

    {plan.name}

    \n
    \n {plan.description}\n
    \n \n \n \n {plan.price.unit}\n \n \n
      \n {plan.features.map((feature) => (\n \n \n {feature}\n \n ))}\n
    \n
    \n \n \n {plan.button.label}\n \n \n \n ))}\n
    \n
    \n
    \n )\n}\n\nexport { Pricing2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/pricing/", + "categories": [ + "pricing" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/pricing-3.json b/public/r/react/styles/base-luma/pricing-3.json new file mode 100644 index 000000000..83896c590 --- /dev/null +++ b/public/r/react/styles/base-luma/pricing-3.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "pricing-3", + "title": "Pricing 3", + "description": "Pricing sections for plan grids, featured offers, and concise offer presentation.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/pricing-3.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Price, PriceUnit, PriceValue } from \"@/components/ui/price\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction Pricing3({\n badge,\n title,\n description,\n locale,\n discountLabel,\n offer,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n description: string\n locale?: string\n discountLabel?: string\n offer: {\n name: string\n description: string\n price: {\n value: number\n compareAt?: number\n currency: string\n unit: string\n }\n features: string[]\n button: {\n label: string\n href: string\n }\n }\n}) {\n return (\n
    \n \n
    \n {badge}\n {title}\n {description}\n
    \n \n \n \n

    {offer.name}

    \n
    \n {offer.description}\n
    \n \n \n \n {offer.price.unit}\n \n \n
      \n {offer.features.map((feature) => (\n
    • \n \n {feature}\n
    • \n ))}\n
    \n
    \n \n \n {offer.button.label}\n \n \n
    \n
    \n
    \n )\n}\n\nexport { Pricing3 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/pricing/", + "categories": [ + "pricing" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/product-1.json b/public/r/react/styles/base-luma/product-1.json new file mode 100644 index 000000000..3abaf049a --- /dev/null +++ b/public/r/react/styles/base-luma/product-1.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "product-1", + "title": "Product 1", + "description": "A focused product section for flagship offers and compact product storytelling.", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/price", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/product-1.tsx", + "content": "import * as React from \"react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Price, PriceUnit, PriceValue } from \"@/components/ui/price\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Product1({\n badge,\n title,\n description,\n image,\n price,\n locale,\n discountLabel,\n note,\n buttons,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n description: string\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n price: {\n value: number\n compareAt?: number\n currency: string\n unit: string\n }\n locale?: string\n discountLabel?: string\n note: string\n buttons: {\n label: string\n href: string\n }[]\n}) {\n return (\n
    \n \n \n
    \n \n {badge}\n \n

    \n {title}\n

    \n

    \n {description}\n

    \n \n \n {price.unit}\n \n

    {note}

    \n
    \n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
    \n
    \n
    \n
    \n )\n}\n\nexport { Product1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/product/", + "categories": [ + "product" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/products-1.json b/public/r/react/styles/base-luma/products-1.json new file mode 100644 index 000000000..ee118592a --- /dev/null +++ b/public/r/react/styles/base-luma/products-1.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "products-1", + "title": "Products 1", + "description": "Product collection layouts for bundles, grouped offers, and category-led merchandising.", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/products-1.tsx", + "content": "import * as React from \"react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Price, PriceUnit, PriceValue } from \"@/components/ui/price\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Products1({\n badge,\n title,\n locale,\n discountLabel,\n products,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n locale?: string\n discountLabel?: string\n products: {\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n title: string\n description: string\n price: {\n value: number\n compareAt?: number\n currency: string\n unit: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n {badge}\n {title}\n
    \n
    \n {products.map((product) => (\n \n \n \n \n

    {product.title}

    \n
    \n {product.description}\n
    \n \n \n \n {product.price.unit}\n \n \n
    \n ))}\n
    \n
    \n
    \n )\n}\n\nexport { Products1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/products/", + "categories": [ + "products" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/products-2.json b/public/r/react/styles/base-luma/products-2.json new file mode 100644 index 000000000..100e2dd22 --- /dev/null +++ b/public/r/react/styles/base-luma/products-2.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "products-2", + "title": "Products 2", + "description": "Product collection layouts for bundles, grouped offers, and category-led merchandising.", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/price", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/products-2.tsx", + "content": "import * as React from \"react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport { Price, PriceUnit, PriceValue } from \"@/components/ui/price\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction Products2({\n badge,\n title,\n locale,\n discountLabel,\n products,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n locale?: string\n discountLabel?: string\n products: {\n title: string\n description: string\n price: {\n value: number\n compareAt?: number\n currency: string\n unit: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n {badge}\n {title}\n
    \n
    \n {products.map((item) => (\n
    \n \n
    \n
    \n

    {item.title}

    \n

    \n {item.description}\n

    \n
    \n \n \n {item.price.unit}\n \n
    \n
    \n ))}\n
    \n
    \n
    \n )\n}\n\nexport { Products2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/products/", + "categories": [ + "products" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/products-3.json b/public/r/react/styles/base-luma/products-3.json new file mode 100644 index 000000000..97c3fb7e6 --- /dev/null +++ b/public/r/react/styles/base-luma/products-3.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "products-3", + "title": "Products 3", + "description": "Product collection layouts for bundles, grouped offers, and category-led merchandising.", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/products-3.tsx", + "content": "import * as React from \"react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Price, PriceValue } from \"@/components/ui/price\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Products3({\n badge,\n title,\n locale,\n discountLabel,\n products,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n locale?: string\n discountLabel?: string\n products: {\n title: string\n description: string\n price: {\n value: number\n compareAt?: number\n currency: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n {badge}\n {title}\n
    \n
    \n {products.map((product) => (\n \n \n \n \n \n \n \n \n

    {product.title}

    \n
    \n {product.description}\n
    \n
    \n ))}\n
    \n
    \n
    \n )\n}\n\nexport { Products3 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/products/", + "categories": [ + "products" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/products-4.json b/public/r/react/styles/base-luma/products-4.json new file mode 100644 index 000000000..c14f9c9fc --- /dev/null +++ b/public/r/react/styles/base-luma/products-4.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "products-4", + "title": "Products 4", + "description": "Product collection layouts for bundles, grouped offers, and category-led merchandising.", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/products-4.tsx", + "content": "import * as React from \"react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Price, PriceUnit, PriceValue } from \"@/components/ui/price\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Products4({\n title,\n description,\n buttons,\n locale,\n discountLabel,\n products,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n locale?: string\n discountLabel?: string\n products: {\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n title: string\n description: string\n price: {\n value: number\n compareAt?: number\n currency: string\n unit: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n
    \n {title}\n

    \n {description}\n

    \n
    \n
    \n {buttons.map(({ href, label }) => (\n \n {label}\n \n ))}\n
    \n
    \n
    \n {products.map((product) => (\n \n \n \n \n

    {product.title}

    \n
    \n {product.description}\n
    \n \n \n \n {product.price.unit}\n \n \n
    \n ))}\n
    \n
    \n
    \n )\n}\n\nexport { Products4 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/products/", + "categories": [ + "products" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/products-5.json b/public/r/react/styles/base-luma/products-5.json new file mode 100644 index 000000000..78ff4e688 --- /dev/null +++ b/public/r/react/styles/base-luma/products-5.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "products-5", + "title": "Products 5", + "description": "Product collection layouts for bundles, grouped offers, and category-led merchandising.", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/products-5.tsx", + "content": "import * as React from \"react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport { Price, PriceUnit, PriceValue } from \"@/components/ui/price\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Products5({\n badge,\n title,\n buttons,\n locale,\n discountLabel,\n products,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n buttons: {\n label: string\n href: string\n }[]\n locale?: string\n discountLabel?: string\n products: {\n image: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n title: string\n description: string\n price: {\n value: number\n compareAt?: number\n currency: string\n unit: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n {badge}\n {title}\n
    \n {buttons.map(({ href, label }) => (\n \n {label}\n \n ))}\n
    \n
    \n
    \n {products.map((product) => (\n \n \n \n \n

    {product.title}

    \n
    \n {product.description}\n
    \n \n \n \n {product.price.unit}\n \n \n
    \n ))}\n
    \n
    \n
    \n )\n}\n\nexport { Products5 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/products/", + "categories": [ + "products" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/progress-examples.json b/public/r/react/styles/base-luma/progress-examples.json new file mode 100644 index 000000000..c457561c8 --- /dev/null +++ b/public/r/react/styles/base-luma/progress-examples.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "progress-examples", + "title": "Progress examples", + "description": "The examples from the shadcn/ui Progress docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/progress", + "@fulldev/select", + "@fulldev/slider" + ], + "files": [ + { + "path": "src/components/examples/progress/progress-controlled.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Progress } from \"@/components/ui/progress\"\nimport { Slider } from \"@/components/ui/slider\"\n\nexport function ProgressControlled() {\n const [value, setValue] = React.useState(50)\n\n return (\n
    \n \n setValue(value as number)}\n min={0}\n max={100}\n step={1}\n />\n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/progress/progress-demo.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Progress } from \"@/components/ui/progress\"\n\nexport function ProgressDemo() {\n const [progress, setProgress] = React.useState(13)\n\n React.useEffect(() => {\n const timer = setTimeout(() => setProgress(66), 500)\n return () => clearTimeout(timer)\n }, [])\n\n return \n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/progress/progress-label.tsx", + "content": "import {\n Progress,\n ProgressLabel,\n ProgressValue,\n} from \"@/components/ui/progress\"\n\nexport function ProgressWithLabel() {\n return (\n \n Upload progress\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/progress/progress-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Progress,\n ProgressLabel,\n ProgressValue,\n} from \"@/components/ui/progress\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n label: \"Upload progress\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n label: \"تقدم الرفع\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n label: \"התקדמות העלאה\",\n },\n },\n}\n\nfunction toArabicNumerals(num: number): string {\n const arabicNumerals = [\"٠\", \"١\", \"٢\", \"٣\", \"٤\", \"٥\", \"٦\", \"٧\", \"٨\", \"٩\"]\n return num\n .toString()\n .split(\"\")\n .map((digit) => arabicNumerals[parseInt(digit, 10)])\n .join(\"\")\n}\n\nexport function ProgressRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n\n const formatNumber = (num: number): string => {\n if (language === \"ar\") {\n return toArabicNumerals(num)\n }\n return num.toString()\n }\n\n return (\n \n {t.label}\n \n {(value) => (\n \n {formatNumber(parseFloat(value ?? \"0\"))}%\n \n )}\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/progress/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/progress.json b/public/r/react/styles/base-luma/progress.json new file mode 100644 index 000000000..fe6baa727 --- /dev/null +++ b/public/r/react/styles/base-luma/progress.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "progress", + "title": "Progress", + "description": "Shows the completion progress of a task as a bar.", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/progress.tsx", + "content": "\"use client\"\n\nimport { Progress as ProgressPrimitive } from \"@base-ui/react/progress\"\nimport { cn } from \"cn\"\n\nfunction Progress({\n className,\n children,\n value,\n ...props\n}: ProgressPrimitive.Root.Props) {\n return (\n \n {children}\n \n \n \n \n )\n}\n\nfunction ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props) {\n return (\n \n )\n}\n\nfunction ProgressIndicator({\n className,\n ...props\n}: ProgressPrimitive.Indicator.Props) {\n return (\n \n )\n}\n\nfunction ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {\n return (\n \n )\n}\n\nfunction ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {\n return (\n \n )\n}\n\nexport {\n Progress,\n ProgressTrack,\n ProgressIndicator,\n ProgressLabel,\n ProgressValue,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/progress/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/questionnaire-examples.json b/public/r/react/styles/base-luma/questionnaire-examples.json new file mode 100644 index 000000000..019c0888b --- /dev/null +++ b/public/r/react/styles/base-luma/questionnaire-examples.json @@ -0,0 +1,92 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "questionnaire-examples", + "title": "Questionnaire examples", + "description": "The examples from the shadcn/ui Questionnaire docs.", + "dependencies": [ + "@shadcn/react", + "sonner", + "zod" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/dialog", + "@fulldev/native-select", + "@fulldev/questionnaire" + ], + "files": [ + { + "path": "src/components/examples/questionnaire/questionnaire-animated.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n { name: \"task\", required: true },\n { name: \"review\", required: true },\n { name: \"delivery\", required: true },\n] as const\n\nconst itemClassName =\n \"data-active:animate-in data-active:fade-in-0 data-active:slide-in-from-bottom-2 data-active:duration-300 motion-reduce:animate-none\"\n\nexport function QuestionnaireAnimated() {\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const formData = new FormData(event.currentTarget)\n\n toast(\"Agent workflow saved\", {\n description: `Task: ${formData.get(\"task\") ?? \"None\"} · Review: ${formData.get(\"review\") ?? \"None\"} · Delivery: ${formData.get(\"delivery\") ?? \"None\"}`,\n })\n }\n\n return (\n \n \n\n \n What should the agent do?\n \n Choose the task for this run.\n \n \n \n Implement the requested change\n \n \n Debug the current behavior\n \n \n Review the implementation\n \n \n \n \n\n \n \n How should the work be reviewed?\n \n \n Select the verification depth.\n \n \n \n Targeted checks\n \n \n Complete test suite\n \n \n Tests and manual QA\n \n \n \n \n\n \n \n How should the result be delivered?\n \n \n Choose the final handoff format.\n \n \n \n Concise summary\n \n \n Summary and changed files\n \n \n Detailed review handoff\n \n \n \n \n\n \n \n Next\n Save workflow\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-card.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\"\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n {\n choices: [{ value: \"fix\" }, { value: \"refactor\" }, { value: \"docs\" }],\n name: \"task\",\n required: true,\n },\n {\n choices: [{ value: \"summary\" }, { value: \"files\" }, { value: \"review\" }],\n name: \"output\",\n required: true,\n },\n] as const\n\nexport function QuestionnaireCard() {\n const taskTitleId = React.useId()\n const outputTitleId = React.useId()\n\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const formData = new FormData(event.currentTarget)\n\n toast(\"Agent task created\", {\n description: `Task: ${formData.get(\"task\") ?? \"None\"} · Handoff: ${formData.get(\"output\") ?? \"None\"}`,\n })\n }\n\n return (\n \n \n \n \n }>\n What should the agent work on?\n \n }>\n Choose the task that should be handled next.\n \n \n \n \n \n \n \n \n Fix the failing tests\n \n \n Refactor the data layer\n \n \n Update the integration guide\n \n \n \n \n \n\n \n \n }>\n What should the final handoff include?\n \n }>\n Pick the level of detail needed for review.\n \n \n \n \n \n \n \n \n Summary only\n \n \n Summary and changed files\n \n \n Full review handoff\n \n \n \n \n \n\n \n \n \n Next\n Create task\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-conditional.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nexport function QuestionnaireConditional() {\n const [runtime, setRuntime] = React.useState(\"local\")\n const items = React.useMemo(\n () => [\n { name: \"runtime\", required: true },\n {\n disabled: runtime !== \"cloud\",\n name: \"environment\",\n required: true,\n },\n { name: \"approval\", required: true },\n ],\n [runtime]\n )\n\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const formData = new FormData(event.currentTarget)\n\n toast(\"Execution plan saved\", {\n description: `Runtime: ${formData.get(\"runtime\") ?? \"None\"} · Environment: ${formData.get(\"environment\") ?? \"Not applicable\"} · Approval: ${formData.get(\"approval\") ?? \"None\"}`,\n })\n }\n\n return (\n \n \n\n \n Where should the agent run?\n \n Cloud runs add an environment question to this flow.\n \n \n setRuntime(\"local\")}\n >\n Local workspace\n \n setRuntime(\"cloud\")}\n >\n Cloud workspace\n \n \n \n \n\n \n \n Which cloud environment should it use?\n \n \n Preview\n Staging\n \n Isolated sandbox\n \n \n \n \n\n \n \n When should the agent request approval?\n \n \n \n Before writing files\n \n \n Before running commands\n \n \n Only for sensitive actions\n \n \n \n \n\n \n \n Next\n Save execution plan\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-controlled.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n { name: \"scope\", required: true },\n { name: \"checks\", required: true },\n { name: \"output\", required: true },\n] as const\n\nconst itemLabels: Record = {\n scope: \"Change scope\",\n checks: \"Verification\",\n output: \"Final output\",\n}\n\nexport function QuestionnaireControlled() {\n const [item, setItem] = React.useState(\"scope\")\n\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const formData = new FormData(event.currentTarget)\n\n toast(\"Agent workflow configured\", {\n description: `Scope: ${formData.get(\"scope\") ?? \"None\"} · Verification: ${formData.get(\"checks\") ?? \"None\"} · Output: ${formData.get(\"output\") ?? \"None\"}`,\n })\n }\n\n return (\n
    \n \n Current checkpoint: {itemLabels[item]}\n

    \n\n \n \n\n \n What may the agent change?\n \n The host stores the active checkpoint while Questionnaire navigates.\n \n \n \n Only the target component\n \n \n Component and related tests\n \n \n The complete feature area\n \n \n \n \n\n \n \n Which verification level should it use?\n \n \n \n Targeted tests\n \n \n Package tests and typecheck\n \n \n Full workspace verification\n \n \n \n \n\n \n \n What should the agent return when finished?\n \n \n \n Concise summary\n \n \n Summary with changed files\n \n \n Detailed implementation handoff\n \n \n \n \n\n \n \n Next\n Save workflow\n \n \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-demo.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireInput,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSkip,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst questionnaireItems = [\n {\n choices: [\n {\n description: \"Show what the agent ran and what came back.\",\n label: \"Tool call timeline\",\n value: \"tool-calls\",\n },\n {\n description: \"Ask before sensitive or destructive actions.\",\n label: \"Approval checkpoints\",\n value: \"approvals\",\n },\n {\n description: \"Make delegated work and results easier to follow.\",\n label: \"Sub-agent handoffs\",\n value: \"handoffs\",\n },\n ],\n description: \"Choose a direction or describe another task.\",\n input: {\n label: \"Another agent feature\",\n placeholder: \"Describe another feature…\",\n },\n name: \"direction\",\n required: true,\n title: \"What should the agent build next?\",\n },\n {\n choices: [\n { label: \"Progress\", value: \"progress\" },\n { label: \"Decisions\", value: \"decisions\" },\n { label: \"Risks\", value: \"risks\" },\n { label: \"Next step\", value: \"next-step\" },\n ],\n description: \"Select all that apply, or skip this question.\",\n multiple: true,\n name: \"signals\",\n required: false,\n title: \"What should every progress update include?\",\n },\n {\n choices: [\n { label: \"Start now\", value: \"now\" },\n { label: \"Next development cycle\", value: \"next-cycle\" },\n { label: \"Add it to the backlog\", value: \"backlog\" },\n ],\n description: \"Choose when the agent should begin the work.\",\n name: \"timing\",\n required: true,\n title: \"When should work begin?\",\n },\n] as const\n\nexport function QuestionnaireDemo() {\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const formData = new FormData(event.currentTarget)\n const answers = {\n direction: formData.get(\"direction\"),\n signals: formData.getAll(\"signals\"),\n timing: formData.get(\"timing\"),\n }\n\n toast(\"Agent plan saved\", {\n description: `Direction: ${answers.direction ?? \"None\"} · Progress signals: ${answers.signals.join(\", \") || \"None\"} · Timing: ${answers.timing ?? \"None\"}`,\n })\n }\n\n return (\n \n \n {questionnaireItems.map((question) => (\n \n {question.title}\n \n {question.description}\n \n \n {question.choices.map((choice) => (\n \n {choice.label}\n {\"description\" in choice ? (\n \n {choice.description}\n \n ) : null}\n \n ))}\n {\"input\" in question ? (\n \n ) : null}\n \n \n \n ))}\n \n \n \n Next\n Save plan\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-dialog.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\"\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n { name: \"scope\", required: true },\n { name: \"tests\", required: true },\n] as const\n\nexport function QuestionnaireDialog() {\n const [open, setOpen] = React.useState(false)\n\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const formData = new FormData(event.currentTarget)\n\n setOpen(false)\n toast(\"Clarification sent\", {\n description: `Scope: ${formData.get(\"scope\") ?? \"None\"} · Verification: ${formData.get(\"tests\") ?? \"None\"}`,\n })\n }\n\n return (\n \n }>\n Open clarification\n \n \n \n \n \n \n }>\n Which files are in scope?\n \n }>\n Choose how broadly the agent can update the workspace.\n \n \n \n \n Component only\n \n \n Complete feature directory\n \n \n Any related workspace file\n \n \n \n \n\n \n \n \n }>\n How much verification is needed?\n \n }>\n Choose the checks the agent should run before handoff.\n \n \n \n \n Targeted tests\n \n \n Package tests\n \n \n Full workspace verification\n \n \n \n \n\n \n }>\n Cancel\n \n \n \n Next\n Send answer\n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-freeform.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireInput,\n QuestionnaireItem,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n {\n choices: [\n { value: \"incremental\" },\n { value: \"module\" },\n { value: \"rewrite\" },\n ],\n name: \"approach\",\n required: true,\n },\n] as const\n\nexport function QuestionnaireFreeform() {\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const approach = new FormData(event.currentTarget).get(\"approach\")\n\n toast(\"Approach selected\", {\n description: `Approach: ${approach ?? \"None\"}`,\n })\n }\n\n return (\n \n \n \n How should the agent approach this refactor?\n \n \n Choose a strategy or write a more specific instruction.\n \n \n \n Make the smallest safe change\n \n \n Refactor one module at a time\n \n \n Replace the implementation completely\n \n \n \n \n \n\n \n Use this approach\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-multiple.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireItem,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n {\n choices: [\n { value: \"source\" },\n { value: \"tests\" },\n { value: \"docs\" },\n { value: \"history\" },\n ],\n name: \"context\",\n required: true,\n },\n] as const\n\nexport function QuestionnaireMultiple() {\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const context = new FormData(event.currentTarget).getAll(\"context\")\n\n toast(\"Context selected\", {\n description: `Context: ${context.join(\", \") || \"None\"}`,\n })\n }\n\n return (\n \n \n \n What context should the agent inspect?\n \n \n Select every source that may affect the implementation.\n \n \n \n Relevant source files\n \n \n Existing tests\n \n \n Architecture documentation\n \n \n Recent commit history\n \n \n \n \n\n \n Share context\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-navigation-state.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { QuestionnaireItemStatus } from \"@shadcn/react/questionnaire\"\nimport { toast } from \"sonner\"\n\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n { name: \"permission\", required: true },\n { name: \"verification\", required: true },\n] as const\n\ntype ItemName = \"permission\" | \"verification\"\n\nexport function QuestionnaireNavigationState() {\n const [item, setItem] = React.useState(\"permission\")\n const [statuses, setStatuses] = React.useState<\n Record\n >({\n permission: \"unanswered\",\n verification: \"unanswered\",\n })\n const unanswered = statuses[item] === \"unanswered\"\n\n function setStatus(name: ItemName, status: QuestionnaireItemStatus) {\n setStatuses((current) => ({ ...current, [name]: status }))\n }\n\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const formData = new FormData(event.currentTarget)\n\n toast(\"Permissions saved\", {\n description: `Permission: ${formData.get(\"permission\") ?? \"None\"} · Verification: ${formData.get(\"verification\") ?? \"None\"}`,\n })\n }\n\n return (\n setItem(nextItem as ItemName)}\n onSubmit={handleSubmit}\n >\n \n\n setStatus(\"permission\", status)}\n >\n What may the agent modify?\n \n Next is intentionally disabled until an answer is selected.\n \n \n Project files\n \n Project files and tests\n \n \n Files, tests, and configuration\n \n \n \n \n\n setStatus(\"verification\", status)}\n >\n \n What must pass before completion?\n \n \n Tests\n \n Tests and types\n \n \n Tests, types, and visual QA\n \n \n \n \n\n \n \n \n Next\n \n \n Save permissions\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-progress.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireError,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n { name: \"scope\", required: true },\n { name: \"strategy\", required: true },\n { name: \"tests\", required: true },\n { name: \"delivery\", required: true },\n] as const\n\nexport function QuestionnaireProgressExample() {\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const formData = new FormData(event.currentTarget)\n\n toast(\"Pull request plan ready\", {\n description: `Scope: ${formData.get(\"scope\") ?? \"None\"} · Commits: ${formData.get(\"strategy\") ?? \"None\"} · Tests: ${formData.get(\"tests\") ?? \"None\"} · Delivery: ${formData.get(\"delivery\") ?? \"None\"}`,\n })\n }\n\n return (\n \n (\n
    \n
    \n {Array.from({ length: state.total }, (_, index) => (\n \n ))}\n
    \n \n Checkpoint {state.current} of {state.total}\n \n
    \n )}\n />\n\n \n How large is the change?\n \n Small patch\n \n Feature-sized change\n \n \n Cross-package change\n \n \n \n \n\n \n \n How should commits be organized?\n \n \n \n Single commit\n \n \n Logical commits\n \n \n Squash before review\n \n \n \n \n\n \n Which tests should run?\n \n \n Targeted tests\n \n \n Package suite\n \n \n Full workspace\n \n \n \n \n\n \n \n How should the work be delivered?\n \n \n Patch only\n \n Committed locally\n \n \n Push a review branch\n \n \n \n \n\n \n \n Next\n Finish plan\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-resume.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireInput,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n { name: \"change\", required: true },\n { name: \"verification\", required: true },\n { name: \"notes\" },\n] as const\n\nexport function QuestionnaireResume() {\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const formData = new FormData(event.currentTarget)\n const answers = {\n change: formData.get(\"change\"),\n verification: formData.getAll(\"verification\"),\n notes: formData.get(\"notes\"),\n }\n\n toast(\"Draft updated\", {\n description: `Migration: ${answers.change ?? \"None\"} · Verification: ${answers.verification.join(\", \") || \"None\"} · Notes: ${answers.notes || \"None\"}`,\n })\n }\n\n return (\n toast(\"Saved answers restored\")}\n onSubmit={handleSubmit}\n >\n \n\n \n What kind of migration is this?\n \n This answer was saved during the previous session.\n \n \n \n Incremental migration\n \n \n Single cutover\n \n \n \n \n\n \n \n How should the migration be verified?\n \n \n These checks were selected during the previous session.\n \n \n \n Run migration tests\n \n \n Run the typecheck\n \n \n Perform a manual smoke test\n \n \n \n \n\n \n \n Anything else the agent should remember?\n \n \n This note was saved with the draft.\n \n \n \n\n \n \n \n Next\n Update draft\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-shortcuts.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport { NativeSelect, NativeSelectOption } from \"@/components/ui/native-select\"\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireItem,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n {\n choices: [{ value: \"inspect\" }, { value: \"tests\" }, { value: \"patch\" }],\n name: \"action\",\n required: true,\n },\n] as const\n\ntype ShortcutMode = React.ComponentProps[\"shortcuts\"]\n\nexport function QuestionnaireShortcuts() {\n const [shortcuts, setShortcuts] = React.useState(\"letters\")\n\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const action = new FormData(event.currentTarget).get(\"action\")\n\n toast(\"Next action selected\", {\n description: `Action: ${action ?? \"None\"} · Shortcuts: ${shortcuts ?? \"none\"}`,\n })\n }\n\n return (\n
    \n {\n const value = event.target.value\n setShortcuts(\n value === \"letters\" || value === \"numbers\" ? value : undefined\n )\n }}\n >\n No shortcuts\n Letters\n Numbers\n \n\n \n \n \n What should the agent do next?\n \n \n Use the displayed shortcut or navigate with the keyboard.\n \n \n \n Inspect the implementation\n \n \n Run the relevant tests\n \n \n Prepare the patch\n \n \n \n \n\n \n Confirm action\n \n \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-skip.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { QuestionnaireItemStatus } from \"@shadcn/react/questionnaire\"\nimport { toast } from \"sonner\"\n\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireInput,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSkip,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n { name: \"task\", required: true },\n { name: \"constraints\" },\n { name: \"review\", required: true },\n] as const\n\nexport function QuestionnaireSkipExample() {\n const [constraintStatus, setConstraintStatus] =\n React.useState(\"unanswered\")\n\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const formData = new FormData(event.currentTarget)\n const answers = {\n task: formData.get(\"task\"),\n constraints: formData.get(\"constraints\"),\n constraintStatus,\n review: formData.get(\"review\"),\n }\n\n toast(\"Agent brief submitted\", {\n description: `Task: ${answers.task ?? \"None\"} · Constraints: ${\n answers.constraintStatus === \"skipped\"\n ? \"Skipped\"\n : (answers.constraints ?? \"None\")\n } · Review: ${answers.review ?? \"None\"}`,\n })\n }\n\n return (\n \n \n\n \n What kind of change is this?\n \n Choose the category that best describes the work.\n \n \n New feature\n Bug fix\n Refactor\n \n \n \n\n \n \n Are there any implementation constraints?\n \n \n Answer if needed, or intentionally skip this question.\n \n \n \n Do not add dependencies\n \n \n Do not change the database\n \n \n Preserve the public API\n \n \n \n \n\n \n \n How should the work be reviewed?\n \n \n Choose the checks the agent should complete before handoff.\n \n \n \n Run the test suite\n \n \n Review the final diff\n \n \n Tests and diff review\n \n \n \n \n\n \n \n \n Next\n Submit brief\n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-validation.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\nimport { z } from \"zod\"\n\nimport {\n Card,\n CardAction,\n CardContent,\n CardFooter,\n CardHeader,\n} from \"@/components/ui/card\"\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from \"@/components/ui/questionnaire\"\n\nconst items = [\n { name: \"detail\", required: true },\n { name: \"audience\", required: true },\n] as const\n\nconst questionnaireSchema = z\n .object({\n detail: z.enum([\"summary\", \"complete\"]),\n audience: z.enum([\"team\", \"public\"]),\n })\n .superRefine((answers, context) => {\n if (answers.audience === \"public\" && answers.detail === \"summary\") {\n context.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n \"Public answers need enough context. Choose a complete answer.\",\n path: [\"detail\"],\n })\n }\n })\n\ntype QuestionnaireItemName = keyof z.infer\ntype QuestionnaireErrors = Partial>\n\nfunction ValidationProgress() {\n return (\n (\n
    \n {state.current} / {state.total}\n
    \n )}\n />\n )\n}\n\nexport function QuestionnaireValidation() {\n const [item, setItem] = React.useState(\"detail\")\n const [errors, setErrors] = React.useState({})\n\n function clearError(name: QuestionnaireItemName) {\n setErrors((currentErrors) => {\n if (!currentErrors[name]) {\n return currentErrors\n }\n\n const nextErrors = { ...currentErrors }\n delete nextErrors[name]\n return nextErrors\n })\n }\n\n function handleSubmit(event: React.FormEvent) {\n event.preventDefault()\n\n const result = questionnaireSchema.safeParse(\n Object.fromEntries(new FormData(event.currentTarget))\n )\n\n if (result.success) {\n setErrors({})\n toast(\"Agent response configured\", {\n description: `Detail: ${result.data.detail} · Audience: ${result.data.audience}`,\n })\n return\n }\n\n const nextErrors: QuestionnaireErrors = {}\n\n for (const issue of result.error.issues) {\n const name = issue.path[0]\n\n if ((name === \"detail\" || name === \"audience\") && !nextErrors[name]) {\n nextErrors[name] = issue.message\n }\n }\n\n const firstInvalidItem = result.error.issues[0]?.path[0]\n\n setErrors(nextErrors)\n\n if (firstInvalidItem === \"detail\" || firstInvalidItem === \"audience\") {\n setItem(firstInvalidItem)\n }\n }\n\n return (\n \n \n \n \n \n How much detail should the answer include?\n \n \n Choose the response depth.\n \n \n \n \n \n \n \n clearError(\"detail\")}\n >\n Concise summary\n \n clearError(\"detail\")}\n >\n Complete answer\n \n \n {errors.detail}\n \n \n\n \n \n Who will read the answer?\n \n Public answers require complete context.\n \n \n \n \n \n \n \n clearError(\"audience\")}\n >\n My team\n \n clearError(\"audience\")}\n >\n Public audience\n \n \n {errors.audience}\n \n \n\n \n \n \n Next\n Validate answers\n \n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/questionnaire/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/questionnaire.json b/public/r/react/styles/base-luma/questionnaire.json new file mode 100644 index 000000000..fead2bfce --- /dev/null +++ b/public/r/react/styles/base-luma/questionnaire.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "questionnaire", + "title": "Questionnaire", + "description": "Asks a series of questions one at a time, with choices, input and shortcuts.", + "dependencies": [ + "@shadcn/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/questionnaire.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Questionnaire as QuestionnairePrimitive } from \"@shadcn/react/questionnaire\"\nimport { cn } from \"cn\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport { buttonVariants, type Button } from \"@/components/ui/button\"\n\nfunction Questionnaire({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction QuestionnaireProgress({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction QuestionnaireItem({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction QuestionnaireTitle({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction QuestionnaireDescription({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction QuestionnaireChoices({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction QuestionnaireChoice({\n children,\n className,\n ...props\n}: React.ComponentProps) {\n return (\n input:focus-visible]:border-ring has-[>input:focus-visible]:ring-ring/50 gap-2.5 rounded-3xl border px-4 py-3 text-sm has-[>input:focus-visible]:ring-3 group/questionnaire-choice relative flex min-h-11 cursor-pointer items-start text-start transition-colors outline-none select-none\",\n \"data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50\",\n className\n )}\n {...props}\n >\n \n \n
  • \n )\n}\n\nfunction QuestionnaireError({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction QuestionnaireActions({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction QuestionnairePrevious({\n children,\n className,\n size = \"default\",\n variant = \"outline\",\n ...props\n}: React.ComponentProps &\n Pick, \"size\" | \"variant\">) {\n return (\n \n {children ?? \"Previous\"}\n \n )\n}\n\nfunction QuestionnaireSkip({\n children,\n className,\n size = \"default\",\n variant = \"outline\",\n ...props\n}: React.ComponentProps &\n Pick, \"size\" | \"variant\">) {\n return (\n \n {children ?? \"Skip\"}\n \n )\n}\n\nfunction QuestionnaireNext({\n children,\n className,\n size = \"default\",\n variant = \"default\",\n ...props\n}: React.ComponentProps &\n Pick, \"size\" | \"variant\">) {\n return (\n \n {children ?? \"Next\"}\n \n )\n}\n\nfunction QuestionnaireSubmit({\n children,\n className,\n size = \"default\",\n variant = \"default\",\n ...props\n}: React.ComponentProps &\n Pick, \"size\" | \"variant\">) {\n return (\n \n {children ?? \"Submit\"}\n \n )\n}\n\nexport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoiceDescription,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireInput,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSkip,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/questionnaire/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/radio-group-examples.json b/public/r/react/styles/base-luma/radio-group-examples.json new file mode 100644 index 000000000..44de38421 --- /dev/null +++ b/public/r/react/styles/base-luma/radio-group-examples.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "radio-group-examples", + "title": "Radio Group examples", + "description": "The examples from the shadcn/ui Radio Group docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/field", + "@fulldev/label", + "@fulldev/radio-group", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/radio-group/radio-group-choice-card.tsx", + "content": "import {\n Field,\n FieldContent,\n FieldDescription,\n FieldLabel,\n FieldTitle,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n\nexport function RadioGroupChoiceCard() {\n return (\n \n \n \n \n Plus\n \n For individuals and small teams.\n \n \n \n \n \n \n \n \n Pro\n For growing businesses.\n \n \n \n \n \n \n \n Enterprise\n \n For large teams and enterprises.\n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-demo.tsx", + "content": "import { Label } from \"@/components/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n\nexport function RadioGroupDemo() {\n return (\n \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-description.tsx", + "content": "import {\n Field,\n FieldContent,\n FieldDescription,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n\nexport function RadioGroupDescription() {\n return (\n \n \n \n \n Default\n \n Standard spacing for most use cases.\n \n \n \n \n \n \n Comfortable\n More space between elements.\n \n \n \n \n \n Compact\n \n Minimal spacing for dense layouts.\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-disabled.tsx", + "content": "import { Field, FieldLabel } from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n\nexport function RadioGroupDisabled() {\n return (\n \n \n \n \n Disabled\n \n \n \n \n \n Option 2\n \n \n \n \n \n Option 3\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-fieldset.tsx", + "content": "import {\n Field,\n FieldDescription,\n FieldLabel,\n FieldLegend,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n\nexport function RadioGroupFieldset() {\n return (\n
    \n Subscription Plan\n \n Yearly and lifetime plans offer significant savings.\n \n \n \n \n \n Monthly ($9.99/month)\n \n \n \n \n \n Yearly ($99.99/year)\n \n \n \n \n \n Lifetime ($299.99)\n \n \n \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-invalid.tsx", + "content": "import {\n Field,\n FieldDescription,\n FieldLabel,\n FieldLegend,\n FieldSet,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\n\nexport function RadioGroupInvalid() {\n return (\n
    \n Notification Preferences\n \n Choose how you want to receive notifications.\n \n \n \n \n \n Email only\n \n \n \n \n \n SMS only\n \n \n \n \n \n Both Email & SMS\n \n \n \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n default: \"Default\",\n defaultDescription: \"Standard spacing for most use cases.\",\n comfortable: \"Comfortable\",\n comfortableDescription: \"More space between elements.\",\n compact: \"Compact\",\n compactDescription: \"Minimal spacing for dense layouts.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n default: \"افتراضي\",\n defaultDescription: \"تباعد قياسي لمعظم حالات الاستخدام.\",\n comfortable: \"مريح\",\n comfortableDescription: \"مساحة أكبر بين العناصر.\",\n compact: \"مضغوط\",\n compactDescription: \"تباعد أدنى للتخطيطات الكثيفة.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n default: \"ברירת מחדל\",\n defaultDescription: \"ריווח סטנדרטי לרוב מקרי השימוש.\",\n comfortable: \"נוח\",\n comfortableDescription: \"יותר מקום בין האלמנטים.\",\n compact: \"קומפקטי\",\n compactDescription: \"ריווח מינימלי לפריסות צפופות.\",\n },\n },\n}\n\nexport function RadioGroupRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n \n \n \n \n \n {t.default}\n \n {t.defaultDescription}\n \n \n \n \n \n \n {t.comfortable}\n \n \n {t.comfortableDescription}\n \n \n \n \n \n \n \n {t.compact}\n \n {t.compactDescription}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/radio-group/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/radio-group.json b/public/r/react/styles/base-luma/radio-group.json new file mode 100644 index 000000000..8d60d8f50 --- /dev/null +++ b/public/r/react/styles/base-luma/radio-group.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "radio-group", + "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": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/radio-group.tsx", + "content": "\"use client\"\n\nimport { Radio as RadioPrimitive } from \"@base-ui/react/radio\"\nimport { RadioGroup as RadioGroupPrimitive } from \"@base-ui/react/radio-group\"\nimport { cn } from \"cn\"\n\nfunction RadioGroup({ className, ...props }: RadioGroupPrimitive.Props) {\n return (\n \n )\n}\n\nfunction RadioGroupItem({ className, ...props }: RadioPrimitive.Root.Props) {\n return (\n \n \n \n \n \n )\n}\n\nexport { RadioGroup, RadioGroupItem }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/radio-group/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/rating.json b/public/r/react/styles/base-luma/rating.json new file mode 100644 index 000000000..e603ac63a --- /dev/null +++ b/public/r/react/styles/base-luma/rating.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "rating", + "title": "Rating", + "description": "A star rating component for displaying ratings visually.", + "dependencies": [ + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/rating.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { StarIcon } from \"lucide-react\"\n\nfunction Rating({\n className,\n value = 5,\n \"aria-label\": ariaLabel = `Rated ${value} out of 5`,\n ...props\n}: React.ComponentProps<\"div\"> & {\n value?: number\n}) {\n return (\n \n {Array.from({ length: 5 }, (_, index) => {\n const fill =\n index < Math.floor(value)\n ? 100\n : index === Math.floor(value)\n ? (value % 1) * 100\n : 0\n return (\n \n \n {fill > 0 && (\n \n \n \n )}\n \n )\n })}\n \n )\n}\n\nexport { Rating }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/rating/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/registry.json b/public/r/react/styles/base-luma/registry.json new file mode 100644 index 000000000..5f56bb4c9 --- /dev/null +++ b/public/r/react/styles/base-luma/registry.json @@ -0,0 +1,7209 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry.json", + "name": "fulldev-react", + "homepage": "https://ui.full.dev/react/", + "items": [ + { + "name": "base", + "type": "registry:base", + "extends": "none", + "title": "Base", + "description": "Sets up a new project with `shadcn init`: style, registry, theme, class helper, and dependencies.", + "docs": "https://ui.full.dev/react/docs/installation/", + "config": { + "style": "base-luma", + "iconLibrary": "lucide", + "tailwind": { + "baseColor": "neutral" + }, + "registries": { + "@fulldev": "https://ui.full.dev/r/react/styles/{style}/{name}.json" + } + }, + "dependencies": [ + "class-variance-authority", + "cn", + "shadcn", + "tw-animate-css" + ], + "files": [ + { + "path": "src/lib/utils.ts", + "type": "registry:lib" + } + ], + "cssVars": { + "theme": { + "font-heading": "var(--font-sans)" + }, + "light": { + "background": "oklch(1 0 0)", + "foreground": "oklch(0.145 0 0)", + "card": "oklch(1 0 0)", + "card-foreground": "oklch(0.145 0 0)", + "popover": "oklch(1 0 0)", + "popover-foreground": "oklch(0.145 0 0)", + "primary": "oklch(0.5488 0.2498 261.783)", + "primary-foreground": "oklch(1 0 0)", + "secondary": "oklch(0.97 0 0)", + "secondary-foreground": "oklch(0.205 0 0)", + "muted": "oklch(0.97 0 0)", + "muted-foreground": "oklch(0.556 0 0)", + "accent": "oklch(0.97 0 0)", + "accent-foreground": "oklch(0.205 0 0)", + "destructive": "oklch(0.577 0.245 27.325)", + "border": "oklch(0.922 0 0)", + "input": "oklch(0.922 0 0)", + "ring": "oklch(0.708 0 0)", + "chart-1": "oklch(0.81 0.1 252)", + "chart-2": "oklch(0.62 0.19 260)", + "chart-3": "oklch(0.55 0.22 263)", + "chart-4": "oklch(0.49 0.22 264)", + "chart-5": "oklch(0.42 0.18 266)", + "sidebar": "oklch(0.985 0 0)", + "sidebar-foreground": "oklch(0.145 0 0)", + "sidebar-primary": "oklch(0.5488 0.2498 261.783)", + "sidebar-primary-foreground": "oklch(1 0 0)", + "sidebar-accent": "oklch(0.97 0 0)", + "sidebar-accent-foreground": "oklch(0.205 0 0)", + "sidebar-border": "oklch(0.922 0 0)", + "sidebar-ring": "oklch(0.708 0 0)", + "radius": "0.625rem", + "shadow-2xs": "0 1px 3px 0px hsl(0 0% 0% / 0.05)", + "shadow-xs": "0 1px 3px 0px hsl(0 0% 0% / 0.05)", + "shadow-sm": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1)", + "shadow": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1)", + "shadow-md": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1)", + "shadow-lg": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1)", + "shadow-xl": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1)", + "shadow-2xl": "0 1px 3px 0px hsl(0 0% 0% / 0.25)" + }, + "dark": { + "background": "oklch(0.145 0 0)", + "foreground": "oklch(0.985 0 0)", + "card": "oklch(0.205 0 0)", + "card-foreground": "oklch(0.985 0 0)", + "popover": "oklch(0.269 0 0)", + "popover-foreground": "oklch(0.985 0 0)", + "primary": "oklch(0.686 0.2105 41.139)", + "primary-foreground": "oklch(1 0 0)", + "secondary": "oklch(0.269 0 0)", + "secondary-foreground": "oklch(0.985 0 0)", + "muted": "oklch(0.269 0 0)", + "muted-foreground": "oklch(0.708 0 0)", + "accent": "oklch(0.371 0 0)", + "accent-foreground": "oklch(0.985 0 0)", + "destructive": "oklch(0.704 0.191 22.216)", + "border": "oklch(0.275 0 0)", + "input": "oklch(0.325 0 0)", + "ring": "oklch(0.556 0 0)", + "chart-1": "oklch(0.81 0.1 252)", + "chart-2": "oklch(0.62 0.19 260)", + "chart-3": "oklch(0.55 0.22 263)", + "chart-4": "oklch(0.49 0.22 264)", + "chart-5": "oklch(0.42 0.18 266)", + "sidebar": "oklch(0.205 0 0)", + "sidebar-foreground": "oklch(0.985 0 0)", + "sidebar-primary": "oklch(0.686 0.2105 41.139)", + "sidebar-primary-foreground": "oklch(1 0 0)", + "sidebar-accent": "oklch(0.269 0 0)", + "sidebar-accent-foreground": "oklch(0.985 0 0)", + "sidebar-border": "oklch(0.275 0 0)", + "sidebar-ring": "oklch(0.439 0 0)", + "shadow-2xs": "0 1px 3px 0px hsl(0 0% 0% / 0.05)", + "shadow-xs": "0 1px 3px 0px hsl(0 0% 0% / 0.05)", + "shadow-sm": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1)", + "shadow": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1)", + "shadow-md": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1)", + "shadow-lg": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1)", + "shadow-xl": "0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1)", + "shadow-2xl": "0 1px 3px 0px hsl(0 0% 0% / 0.25)" + } + }, + "css": { + "@import \"tw-animate-css\"": {}, + "@import \"shadcn/tailwind.css\"": {}, + "@layer base": { + "*": { + "@apply border-border outline-ring/50": {} + }, + "html": { + "@apply font-sans": {} + }, + "body": { + "@apply bg-background text-foreground": {} + } + }, + "@media (prefers-reduced-motion: reduce)": { + "*, ::before, ::after": { + "animation-duration": "0.01ms !important", + "animation-iteration-count": "1 !important", + "transition-duration": "0.01ms !important", + "scroll-behavior": "auto !important" + } + } + } + }, + { + "name": "init", + "type": "registry:lib", + "title": "Init", + "description": "Class helper, dependencies, and base styles for an existing project. Leaves theme tokens alone.", + "docs": "https://ui.full.dev/react/docs/installation/", + "dependencies": [ + "class-variance-authority", + "cn", + "shadcn", + "tw-animate-css" + ], + "files": [ + { + "path": "src/lib/utils.ts", + "type": "registry:lib" + } + ], + "css": { + "@import \"tw-animate-css\"": {}, + "@import \"shadcn/tailwind.css\"": {}, + "@layer base": { + "*": { + "@apply border-border outline-ring/50": {} + }, + "html": { + "@apply font-sans": {} + }, + "body": { + "@apply bg-background text-foreground": {} + } + }, + "@media (prefers-reduced-motion: reduce)": { + "*, ::before, ::after": { + "animation-duration": "0.01ms !important", + "animation-iteration-count": "1 !important", + "transition-duration": "0.01ms !important", + "scroll-behavior": "auto !important" + } + } + } + }, + { + "name": "components", + "type": "registry:item", + "title": "All components", + "description": "Installs every Fulldev UI React component.", + "docs": "https://ui.full.dev/react/components/", + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/alert", + "@fulldev/alert-dialog", + "@fulldev/aspect-ratio", + "@fulldev/attachment", + "@fulldev/avatar", + "@fulldev/badge", + "@fulldev/banner", + "@fulldev/breadcrumb", + "@fulldev/bubble", + "@fulldev/button", + "@fulldev/button-group", + "@fulldev/calendar", + "@fulldev/card", + "@fulldev/carousel", + "@fulldev/chart", + "@fulldev/checkbox", + "@fulldev/collapsible", + "@fulldev/combobox", + "@fulldev/command", + "@fulldev/context-menu", + "@fulldev/dialog", + "@fulldev/direction", + "@fulldev/drawer", + "@fulldev/dropdown-menu", + "@fulldev/empty", + "@fulldev/field", + "@fulldev/form", + "@fulldev/header", + "@fulldev/hover-card", + "@fulldev/icon", + "@fulldev/input", + "@fulldev/input-group", + "@fulldev/input-otp", + "@fulldev/item", + "@fulldev/kbd", + "@fulldev/label", + "@fulldev/layout", + "@fulldev/logo", + "@fulldev/marker", + "@fulldev/marquee", + "@fulldev/menubar", + "@fulldev/message", + "@fulldev/message-scroller", + "@fulldev/native-select", + "@fulldev/navigation-menu", + "@fulldev/pagination", + "@fulldev/popover", + "@fulldev/price", + "@fulldev/progress", + "@fulldev/questionnaire", + "@fulldev/radio-group", + "@fulldev/rating", + "@fulldev/resizable", + "@fulldev/scroll-area", + "@fulldev/section", + "@fulldev/select", + "@fulldev/separator", + "@fulldev/sheet", + "@fulldev/sidebar", + "@fulldev/skeleton", + "@fulldev/slider", + "@fulldev/sonner", + "@fulldev/spinner", + "@fulldev/switch", + "@fulldev/table", + "@fulldev/tabs", + "@fulldev/textarea", + "@fulldev/theme-toggle", + "@fulldev/toast", + "@fulldev/toc", + "@fulldev/toggle", + "@fulldev/toggle-group", + "@fulldev/tooltip", + "@fulldev/typography", + "@fulldev/video" + ] + }, + { + "name": "blocks", + "type": "registry:item", + "title": "All blocks", + "description": "Installs every Fulldev UI React block.", + "docs": "https://ui.full.dev/react/blocks/", + "registryDependencies": [ + "@fulldev/article-1", + "@fulldev/article-2", + "@fulldev/articles-1", + "@fulldev/articles-2", + "@fulldev/articles-3", + "@fulldev/articles-4", + "@fulldev/banner-1", + "@fulldev/banner-2", + "@fulldev/blocks-1", + "@fulldev/contact-1", + "@fulldev/contact-2", + "@fulldev/contact-3", + "@fulldev/content-1", + "@fulldev/content-2", + "@fulldev/content-3", + "@fulldev/content-4", + "@fulldev/cta-1", + "@fulldev/cta-2", + "@fulldev/cta-3", + "@fulldev/cta-4", + "@fulldev/cta-5", + "@fulldev/cta-6", + "@fulldev/cta-7", + "@fulldev/cta-8", + "@fulldev/doc-1", + "@fulldev/faqs-1", + "@fulldev/faqs-2", + "@fulldev/faqs-3", + "@fulldev/faqs-4", + "@fulldev/features-1", + "@fulldev/features-2", + "@fulldev/features-3", + "@fulldev/features-4", + "@fulldev/features-5", + "@fulldev/features-6", + "@fulldev/footer-1", + "@fulldev/footer-2", + "@fulldev/footer-3", + "@fulldev/header-1", + "@fulldev/header-2", + "@fulldev/header-3", + "@fulldev/header-4", + "@fulldev/header-5", + "@fulldev/hero-1", + "@fulldev/hero-10", + "@fulldev/hero-11", + "@fulldev/hero-12", + "@fulldev/hero-13", + "@fulldev/hero-2", + "@fulldev/hero-3", + "@fulldev/hero-4", + "@fulldev/hero-5", + "@fulldev/hero-6", + "@fulldev/hero-7", + "@fulldev/hero-8", + "@fulldev/hero-9", + "@fulldev/links-2", + "@fulldev/logos-1", + "@fulldev/logos-2", + "@fulldev/logos-3", + "@fulldev/pricing-1", + "@fulldev/pricing-2", + "@fulldev/pricing-3", + "@fulldev/product-1", + "@fulldev/products-1", + "@fulldev/products-2", + "@fulldev/products-3", + "@fulldev/products-4", + "@fulldev/products-5", + "@fulldev/reviews-1", + "@fulldev/reviews-2", + "@fulldev/reviews-3", + "@fulldev/reviews-4", + "@fulldev/reviews-5", + "@fulldev/services-1", + "@fulldev/services-2", + "@fulldev/services-3", + "@fulldev/services-4", + "@fulldev/services-5", + "@fulldev/services-6", + "@fulldev/services-7", + "@fulldev/sidebar-1" + ] + }, + { + "name": "accordion", + "type": "registry:ui", + "title": "Accordion", + "description": "A vertically stacked set of interactive headings that each reveal a section of content.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/accordion/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/accordion.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "alert", + "type": "registry:ui", + "title": "Alert", + "description": "Displays a callout for user attention.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/alert/", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/alert.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "alert-dialog", + "type": "registry:ui", + "title": "Alert Dialog", + "description": "A modal dialog for important confirmations that expects a response.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/alert-dialog/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/alert-dialog.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "aspect-ratio", + "type": "registry:ui", + "title": "Aspect Ratio", + "description": "Displays content within a desired ratio.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/aspect-ratio/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/aspect-ratio.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "attachment", + "type": "registry:ui", + "title": "Attachment", + "description": "Displays a file or image attachment with media, metadata, state, and actions.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/attachment/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/attachment.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "avatar", + "type": "registry:ui", + "title": "Avatar", + "description": "An image element with a fallback for representing the user.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/avatar/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/avatar.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "badge", + "type": "registry:ui", + "title": "Badge", + "description": "Displays a badge or a component that looks like a badge.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/badge/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/badge.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "banner", + "type": "registry:ui", + "title": "Banner", + "description": "A full-width container for important messages or announcements.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/banner/", + "dependencies": [ + "class-variance-authority", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/banner.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "breadcrumb", + "type": "registry:ui", + "title": "Breadcrumb", + "description": "Displays the path to the current resource using a hierarchy of links.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/breadcrumb/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/breadcrumb.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "bubble", + "type": "registry:ui", + "title": "Bubble", + "description": "Displays a chat message in a bubble, with grouping and reactions.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/bubble/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/bubble.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "button", + "type": "registry:ui", + "title": "Button", + "description": "Displays a button or a component that looks like a button.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/button/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/button.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "button-group", + "type": "registry:ui", + "title": "Button Group", + "description": "Groups related controls with connected edges and consistent focus behavior.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/button-group/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/ui/button-group.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "calendar", + "type": "registry:ui", + "title": "Calendar", + "description": "A calendar for picking a date, several dates, or a range.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/calendar/", + "dependencies": [ + "cn", + "lucide-react", + "react-day-picker" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/calendar.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "card", + "type": "registry:ui", + "title": "Card", + "description": "Displays a card with header, content, and footer.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/card/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/card.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "carousel", + "type": "registry:ui", + "title": "Carousel", + "description": "A carousel with motion, swipe and responsive slides built using Embla.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/carousel/", + "dependencies": [ + "cn", + "embla-carousel-react@8.6.0", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/carousel.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "chart", + "type": "registry:ui", + "title": "Chart", + "description": "Charts built with Recharts, themed with the chart color tokens.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/chart/", + "dependencies": [ + "cn", + "recharts@3.8.0" + ], + "files": [ + { + "path": "src/components/ui/chart.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "checkbox", + "type": "registry:ui", + "title": "Checkbox", + "description": "A control that allows the user to toggle between checked and not checked.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/checkbox/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/checkbox.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "collapsible", + "type": "registry:ui", + "title": "Collapsible", + "description": "An interactive component which expands/collapses a panel.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/collapsible/", + "dependencies": [ + "@base-ui/react" + ], + "files": [ + { + "path": "src/components/ui/collapsible.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "combobox", + "type": "registry:ui", + "title": "Combobox", + "description": "Autocomplete input with a list of suggestions.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/combobox/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/input-group" + ], + "files": [ + { + "path": "src/components/ui/combobox.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "command", + "type": "registry:ui", + "title": "Command", + "description": "Command menu for search and quick actions.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/command/", + "dependencies": [ + "cmdk", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/dialog", + "@fulldev/input-group" + ], + "files": [ + { + "path": "src/components/ui/command.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "context-menu", + "type": "registry:ui", + "title": "Context Menu", + "description": "Displays a menu of actions, opened with a right click or a long press.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/context-menu/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/context-menu.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "dialog", + "type": "registry:ui", + "title": "Dialog", + "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/react/components/dialog/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/dialog.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "direction", + "type": "registry:ui", + "title": "Direction", + "description": "Sets the text direction for the components inside it.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/direction/", + "dependencies": [ + "@base-ui/react" + ], + "files": [ + { + "path": "src/components/ui/direction.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "drawer", + "type": "registry:ui", + "title": "Drawer", + "description": "A swipeable panel that opens from an edge of the screen.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/drawer/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/drawer.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "dropdown-menu", + "type": "registry:ui", + "title": "Dropdown Menu", + "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/react/components/dropdown-menu/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/dropdown-menu.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "empty", + "type": "registry:ui", + "title": "Empty", + "description": "Displays an empty state placeholder with optional media, title, and description.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/empty/", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/empty.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "field", + "type": "registry:ui", + "title": "Field", + "description": "Combine labels, controls, and help text to compose accessible form fields and grouped inputs.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/field/", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/label", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/ui/field.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "form", + "type": "registry:ui", + "title": "Form", + "description": "A form wrapper with vertical spacing for the field components.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/form/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/form.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "header", + "type": "registry:ui", + "title": "Header", + "description": "A responsive site header with grouped content.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/header/", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/header.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "hover-card", + "type": "registry:ui", + "title": "Hover Card", + "description": "For sighted users to preview content available behind a link.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/hover-card/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/hover-card.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "icon", + "type": "registry:ui", + "title": "Icon", + "description": "Renders a Lucide icon or a social brand logo by name, or the icon for a link.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/icon/", + "dependencies": [ + "cn", + "lucide-react", + "simple-icons" + ], + "files": [ + { + "path": "src/components/ui/icon.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "input", + "type": "registry:ui", + "title": "Input", + "description": "Displays a form input field or a component that looks like an input field.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/input/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/input.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "input-group", + "type": "registry:ui", + "title": "Input Group", + "description": "Add addons, buttons, and helper content to inputs.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/input-group/", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/input", + "@fulldev/textarea" + ], + "files": [ + { + "path": "src/components/ui/input-group.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "input-otp", + "type": "registry:ui", + "title": "Input OTP", + "description": "An accessible one-time password input with copy and paste support.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/input-otp/", + "dependencies": [ + "cn", + "input-otp", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/input-otp.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "item", + "type": "registry:ui", + "title": "Item", + "description": "A flexible container for displaying content items with various styles.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/item/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/ui/item.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "kbd", + "type": "registry:ui", + "title": "Kbd", + "description": "Used to display textual user input from keyboard.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/kbd/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/kbd.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "label", + "type": "registry:ui", + "title": "Label", + "description": "Renders an accessible label associated with a control.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/label/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/label.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "layout", + "type": "registry:ui", + "title": "Layout", + "description": "Page-shell primitives for the root html, head, body, and main structure.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/layout/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/layout.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "logo", + "type": "registry:ui", + "title": "Logo", + "description": "A component for displaying a brand logo.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/logo/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/logo.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "marker", + "type": "registry:ui", + "title": "Marker", + "description": "Marks a status or event in a conversation, with an icon and text.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/marker/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/marker.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "marquee", + "type": "registry:ui", + "title": "Marquee", + "description": "A continuously scrolling row of content, with a pause control and a static fallback.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/marquee/", + "dependencies": [ + "class-variance-authority", + "cn", + "embla-carousel-auto-scroll@8.6.0", + "embla-carousel-react@8.6.0", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/marquee.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "menubar", + "type": "registry:ui", + "title": "Menubar", + "description": "A persistent menu bar with quick access to a set of commands.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/menubar/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/dropdown-menu" + ], + "files": [ + { + "path": "src/components/ui/menubar.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "message", + "type": "registry:ui", + "title": "Message", + "description": "A chat message with avatar, header, content and footer.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/message/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/message.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "message-scroller", + "type": "registry:ui", + "title": "Message Scroller", + "description": "Scrolls a conversation and keeps the latest message in view.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/message-scroller/", + "dependencies": [ + "@shadcn/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/message-scroller.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "native-select", + "type": "registry:ui", + "title": "Native Select", + "description": "A styled native HTML select element with consistent design system integration.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/native-select/", + "dependencies": [ + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/native-select.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "navigation-menu", + "type": "registry:ui", + "title": "Navigation Menu", + "description": "A collection of links for navigating websites.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/navigation-menu/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/navigation-menu.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "pagination", + "type": "registry:ui", + "title": "Pagination", + "description": "Page navigation with previous, next, numbered, and overflow links.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/pagination/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/pagination.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "popover", + "type": "registry:ui", + "title": "Popover", + "description": "Displays rich content in a floating layer, triggered by a button.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/popover/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/popover.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "price", + "type": "registry:ui", + "title": "Price", + "description": "A flexible price display component for showing pricing information.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/price/", + "dependencies": [ + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/price.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "progress", + "type": "registry:ui", + "title": "Progress", + "description": "Shows the completion progress of a task as a bar.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/progress/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/progress.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "questionnaire", + "type": "registry:ui", + "title": "Questionnaire", + "description": "Asks a series of questions one at a time, with choices, input and shortcuts.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/questionnaire/", + "dependencies": [ + "@shadcn/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/questionnaire.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "radio-group", + "type": "registry:ui", + "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.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/radio-group/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/radio-group.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "rating", + "type": "registry:ui", + "title": "Rating", + "description": "A star rating component for displaying ratings visually.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/rating/", + "dependencies": [ + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/rating.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "resizable", + "type": "registry:ui", + "title": "Resizable", + "description": "Accessible panel groups with pointer and keyboard resizing.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/resizable/", + "dependencies": [ + "cn", + "react-resizable-panels" + ], + "files": [ + { + "path": "src/components/ui/resizable.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "scroll-area", + "type": "registry:ui", + "title": "Scroll Area", + "description": "Native scrolling with custom, cross-browser scrollbars.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/scroll-area/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/scroll-area.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "section", + "type": "registry:ui", + "title": "Section", + "description": "A layout component for organizing page content into sections.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/section/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/section.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "select", + "type": "registry:ui", + "title": "Select", + "description": "Displays a list of options for the user to pick from, triggered by a button.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/select/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/select.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "separator", + "type": "registry:ui", + "title": "Separator", + "description": "Visually or semantically separates content.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/separator/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/separator.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "sheet", + "type": "registry:ui", + "title": "Sheet", + "description": "A sliding panel component that appears from the edge of the screen.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/sheet/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/sheet.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "sidebar", + "type": "registry:ui", + "title": "Sidebar", + "description": "A composable, themeable and customizable sidebar component.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/sidebar/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/input", + "@fulldev/separator", + "@fulldev/sheet", + "@fulldev/skeleton", + "@fulldev/tooltip", + "@fulldev/use-mobile" + ], + "files": [ + { + "path": "src/components/ui/sidebar.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "skeleton", + "type": "registry:ui", + "title": "Skeleton", + "description": "Use a skeleton as a placeholder while content is loading.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/skeleton/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/skeleton.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "slider", + "type": "registry:ui", + "title": "Slider", + "description": "An input where the user selects a value from within a given range.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/slider/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/slider.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "sonner", + "type": "registry:ui", + "title": "Sonner", + "description": "Toast notifications with Sonner, themed with the site tokens.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/sonner/", + "dependencies": [ + "lucide-react", + "next-themes", + "sonner" + ], + "files": [ + { + "path": "src/components/ui/sonner.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "spinner", + "type": "registry:ui", + "title": "Spinner", + "description": "An animated loading indicator.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/spinner/", + "dependencies": [ + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/spinner.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "switch", + "type": "registry:ui", + "title": "Switch", + "description": "A control that allows the user to toggle between checked and not checked.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/switch/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/switch.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "table", + "type": "registry:ui", + "title": "Table", + "description": "A data table component that displays information in rows and columns.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/table/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/table.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "tabs", + "type": "registry:ui", + "title": "Tabs", + "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/react/components/tabs/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/tabs.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "textarea", + "type": "registry:ui", + "title": "Textarea", + "description": "Displays a form textarea or a component that looks like a textarea.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/textarea/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/textarea.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "theme-toggle", + "type": "registry:ui", + "title": "Theme Toggle", + "description": "A two-state theme toggle that switches immediately between light and dark mode.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/theme-toggle/", + "dependencies": [ + "cn", + "lucide-react", + "next-themes" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/theme-toggle.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "toast", + "type": "registry:ui", + "title": "Toast", + "description": "A brief notification that appears without interrupting the user.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/toast/", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/toast.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "toc", + "type": "registry:ui", + "title": "Toc", + "description": "Displays a simple table of contents for page sections and subsections.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/toc/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/toc.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "toggle", + "type": "registry:ui", + "title": "Toggle", + "description": "A two-state button that can be either on or off.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/toggle/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/toggle.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "toggle-group", + "type": "registry:ui", + "title": "Toggle Group", + "description": "A set of two-state buttons that can be toggled independently or as a single choice.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/toggle-group/", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "registryDependencies": [ + "@fulldev/toggle" + ], + "files": [ + { + "path": "src/components/ui/toggle-group.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "tooltip", + "type": "registry:ui", + "title": "Tooltip", + "description": "Displays contextual information when a user hovers or focuses a trigger.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/tooltip/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/tooltip.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "typography", + "type": "registry:ui", + "title": "Typography", + "description": "Automatic prose styling and semantic text primitives for documentation and content-heavy interfaces.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/typography/", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/typography.tsx", + "type": "registry:ui" + }, + { + "path": "src/components/ui/typeset.css", + "type": "registry:ui" + } + ] + }, + { + "name": "video", + "type": "registry:ui", + "title": "Video", + "description": "A responsive video component that supports YouTube videos and shorts.", + "categories": [ + "ui" + ], + "docs": "https://ui.full.dev/react/components/video/", + "dependencies": [ + "cn" + ], + "files": [ + { + "path": "src/components/ui/video.tsx", + "type": "registry:ui" + } + ] + }, + { + "name": "use-mobile", + "type": "registry:hook", + "title": "Use Mobile", + "description": "Tracks whether the viewport is below the mobile breakpoint.", + "files": [ + { + "path": "src/hooks/use-mobile.ts", + "type": "registry:hook" + } + ] + }, + { + "name": "article-1", + "type": "registry:block", + "title": "Article 1", + "description": "Editorial article layouts for long-form stories, interviews, and analysis.", + "categories": [ + "article" + ], + "docs": "https://ui.full.dev/react/blocks/article/", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/article-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "article-2", + "type": "registry:block", + "title": "Article 2", + "description": "Editorial article layouts for long-form stories, interviews, and analysis.", + "categories": [ + "article" + ], + "docs": "https://ui.full.dev/react/blocks/article/", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/article-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "articles-1", + "type": "registry:block", + "title": "Articles 1", + "description": "Collection and listing layouts for journals, magazines, and editorial feeds.", + "categories": [ + "articles" + ], + "docs": "https://ui.full.dev/react/blocks/articles/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/articles-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "articles-2", + "type": "registry:block", + "title": "Articles 2", + "description": "Collection and listing layouts for journals, magazines, and editorial feeds.", + "categories": [ + "articles" + ], + "docs": "https://ui.full.dev/react/blocks/articles/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/badge", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/articles-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "articles-3", + "type": "registry:block", + "title": "Articles 3", + "description": "Collection and listing layouts for journals, magazines, and editorial feeds.", + "categories": [ + "articles" + ], + "docs": "https://ui.full.dev/react/blocks/articles/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/articles-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "articles-4", + "type": "registry:block", + "title": "Articles 4", + "description": "Collection and listing layouts for journals, magazines, and editorial feeds.", + "categories": [ + "articles" + ], + "docs": "https://ui.full.dev/react/blocks/articles/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/articles-4.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "banner-1", + "type": "registry:block", + "title": "Banner 1", + "description": "Announcement and promo bars that sit above or inside page content.", + "categories": [ + "banner" + ], + "docs": "https://ui.full.dev/react/blocks/banner/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/banner" + ], + "files": [ + { + "path": "src/components/blocks/banner-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "banner-2", + "type": "registry:block", + "title": "Banner 2", + "description": "Announcement and promo bars that sit above or inside page content.", + "categories": [ + "banner" + ], + "docs": "https://ui.full.dev/react/blocks/banner/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/banner", + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/blocks/banner-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "blocks-1", + "type": "registry:block", + "title": "Blocks 1", + "categories": [ + "blocks" + ], + "docs": "https://ui.full.dev/react/blocks/blocks/", + "dependencies": [ + "cn", + "lucide-react", + "simple-icons" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/section", + "@fulldev/typography" + ], + "files": [ + { + "path": "src/components/blocks/blocks-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "contact-1", + "type": "registry:block", + "title": "Contact 1", + "description": "Contact sections for project inquiries, support, and sales conversations.", + "categories": [ + "contact" + ], + "docs": "https://ui.full.dev/react/blocks/contact/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/contact-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "contact-2", + "type": "registry:block", + "title": "Contact 2", + "description": "Contact sections for project inquiries, support, and sales conversations.", + "categories": [ + "contact" + ], + "docs": "https://ui.full.dev/react/blocks/contact/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/contact-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "contact-3", + "type": "registry:block", + "title": "Contact 3", + "description": "Contact sections for project inquiries, support, and sales conversations.", + "categories": [ + "contact" + ], + "docs": "https://ui.full.dev/react/blocks/contact/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/contact-3.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "content-1", + "type": "registry:block", + "title": "Content 1", + "description": "Flexible narrative content sections for explainers, comparisons, and supporting context.", + "categories": [ + "content" + ], + "docs": "https://ui.full.dev/react/blocks/content/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/content-1.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "content-2", + "type": "registry:block", + "title": "Content 2", + "description": "Flexible narrative content sections for explainers, comparisons, and supporting context.", + "categories": [ + "content" + ], + "docs": "https://ui.full.dev/react/blocks/content/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/content-2.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "content-3", + "type": "registry:block", + "title": "Content 3", + "description": "Flexible narrative content sections for explainers, comparisons, and supporting context.", + "categories": [ + "content" + ], + "docs": "https://ui.full.dev/react/blocks/content/", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/content-3.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "content-4", + "type": "registry:block", + "title": "Content 4", + "description": "Flexible narrative content sections for explainers, comparisons, and supporting context.", + "categories": [ + "content" + ], + "docs": "https://ui.full.dev/react/blocks/content/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/content-4.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "cta-1", + "type": "registry:block", + "title": "Cta 1", + "description": "Call-to-action sections that close pages, bridge sections, or reinforce a launch moment.", + "categories": [ + "cta" + ], + "docs": "https://ui.full.dev/react/blocks/cta/", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/cta-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "cta-2", + "type": "registry:block", + "title": "Cta 2", + "description": "Call-to-action sections that close pages, bridge sections, or reinforce a launch moment.", + "categories": [ + "cta" + ], + "docs": "https://ui.full.dev/react/blocks/cta/", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/cta-2.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "cta-3", + "type": "registry:block", + "title": "Cta 3", + "description": "Call-to-action sections that close pages, bridge sections, or reinforce a launch moment.", + "categories": [ + "cta" + ], + "docs": "https://ui.full.dev/react/blocks/cta/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/cta-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "cta-4", + "type": "registry:block", + "title": "Cta 4", + "description": "Call-to-action sections that close pages, bridge sections, or reinforce a launch moment.", + "categories": [ + "cta" + ], + "docs": "https://ui.full.dev/react/blocks/cta/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/cta-4.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "cta-5", + "type": "registry:block", + "title": "Cta 5", + "description": "Call-to-action sections that close pages, bridge sections, or reinforce a launch moment.", + "categories": [ + "cta" + ], + "docs": "https://ui.full.dev/react/blocks/cta/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/cta-5.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "cta-6", + "type": "registry:block", + "title": "Cta 6", + "description": "Call-to-action sections that close pages, bridge sections, or reinforce a launch moment.", + "categories": [ + "cta" + ], + "docs": "https://ui.full.dev/react/blocks/cta/", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/cta-6.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "cta-7", + "type": "registry:block", + "title": "Cta 7", + "description": "Call-to-action sections that close pages, bridge sections, or reinforce a launch moment.", + "categories": [ + "cta" + ], + "docs": "https://ui.full.dev/react/blocks/cta/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/cta-7.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "cta-8", + "type": "registry:block", + "title": "Cta 8", + "description": "Call-to-action sections that close pages, bridge sections, or reinforce a launch moment.", + "categories": [ + "cta" + ], + "docs": "https://ui.full.dev/react/blocks/cta/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/cta-8.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "doc-1", + "type": "registry:block", + "title": "Doc 1", + "description": "Documentation page shells for component pages with content, table of contents, and contextual links.", + "categories": [ + "doc" + ], + "docs": "https://ui.full.dev/react/blocks/doc/", + "dependencies": [ + "cn", + "lucide-react", + "simple-icons" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/dropdown-menu", + "@fulldev/section", + "@fulldev/toc", + "@fulldev/typography" + ], + "files": [ + { + "path": "src/components/blocks/doc-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "faqs-1", + "type": "registry:block", + "title": "Faqs 1", + "description": "FAQ sections for product pages, launches, and documentation support content.", + "categories": [ + "faqs" + ], + "docs": "https://ui.full.dev/react/blocks/faqs/", + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/faqs-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "faqs-2", + "type": "registry:block", + "title": "Faqs 2", + "description": "FAQ sections for product pages, launches, and documentation support content.", + "categories": [ + "faqs" + ], + "docs": "https://ui.full.dev/react/blocks/faqs/", + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/faqs-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "faqs-3", + "type": "registry:block", + "title": "Faqs 3", + "description": "FAQ sections for product pages, launches, and documentation support content.", + "categories": [ + "faqs" + ], + "docs": "https://ui.full.dev/react/blocks/faqs/", + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/badge", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/faqs-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "faqs-4", + "type": "registry:block", + "title": "Faqs 4", + "description": "FAQ sections for product pages, launches, and documentation support content.", + "categories": [ + "faqs" + ], + "docs": "https://ui.full.dev/react/blocks/faqs/", + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/faqs-4.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "features-1", + "type": "registry:block", + "title": "Features 1", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "categories": [ + "features" + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/features-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "features-2", + "type": "registry:block", + "title": "Features 2", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "categories": [ + "features" + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "registryDependencies": [ + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/features-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "features-3", + "type": "registry:block", + "title": "Features 3", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "categories": [ + "features" + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "registryDependencies": [ + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/features-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "features-4", + "type": "registry:block", + "title": "Features 4", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "categories": [ + "features" + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/features-4.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "features-5", + "type": "registry:block", + "title": "Features 5", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "categories": [ + "features" + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "registryDependencies": [ + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/features-5.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "features-6", + "type": "registry:block", + "title": "Features 6", + "description": "Feature section layouts for product narratives, launch pages, and capability overviews.", + "categories": [ + "features" + ], + "docs": "https://ui.full.dev/react/blocks/features/", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/features-6.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "footer-1", + "type": "registry:block", + "title": "Footer 1", + "description": "Footer layouts for utility navigation, brand presence, and last-mile calls to action.", + "categories": [ + "footer" + ], + "docs": "https://ui.full.dev/react/blocks/footer/", + "registryDependencies": [ + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/footer-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "footer-2", + "type": "registry:block", + "title": "Footer 2", + "description": "Footer layouts for utility navigation, brand presence, and last-mile calls to action.", + "categories": [ + "footer" + ], + "docs": "https://ui.full.dev/react/blocks/footer/", + "registryDependencies": [ + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/footer-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "footer-3", + "type": "registry:block", + "title": "Footer 3", + "description": "Footer layouts for utility navigation, brand presence, and last-mile calls to action.", + "categories": [ + "footer" + ], + "docs": "https://ui.full.dev/react/blocks/footer/", + "registryDependencies": [ + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/footer-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "header-1", + "type": "registry:block", + "title": "Header 1", + "description": "Header layouts for brand, navigation, and high-level page actions.", + "categories": [ + "header" + ], + "docs": "https://ui.full.dev/react/blocks/header/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/navigation-menu", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/blocks/header-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "header-2", + "type": "registry:block", + "title": "Header 2", + "description": "Header layouts for brand, navigation, and high-level page actions.", + "categories": [ + "header" + ], + "docs": "https://ui.full.dev/react/blocks/header/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/navigation-menu", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/blocks/header-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "header-3", + "type": "registry:block", + "title": "Header 3", + "description": "Header layouts for brand, navigation, and high-level page actions.", + "categories": [ + "header" + ], + "docs": "https://ui.full.dev/react/blocks/header/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/navigation-menu", + "@fulldev/separator", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/blocks/header-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "header-4", + "type": "registry:block", + "title": "Header 4", + "description": "Header layouts for brand, navigation, and high-level page actions.", + "categories": [ + "header" + ], + "docs": "https://ui.full.dev/react/blocks/header/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/navigation-menu", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/blocks/header-4.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "header-5", + "type": "registry:block", + "title": "Header 5", + "description": "Header layouts for brand, navigation, and high-level page actions.", + "categories": [ + "header" + ], + "docs": "https://ui.full.dev/react/blocks/header/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/logo", + "@fulldev/navigation-menu", + "@fulldev/separator", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/blocks/header-5.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-1", + "type": "registry:block", + "title": "Hero 1", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-10", + "type": "registry:block", + "title": "Hero 10", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-10.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-11", + "type": "registry:block", + "title": "Hero 11", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-11.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-12", + "type": "registry:block", + "title": "Hero 12", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-12.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-13", + "type": "registry:block", + "title": "Hero 13", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-13.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-2", + "type": "registry:block", + "title": "Hero 2", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-3", + "type": "registry:block", + "title": "Hero 3", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-4", + "type": "registry:block", + "title": "Hero 4", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-4.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-5", + "type": "registry:block", + "title": "Hero 5", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-5.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-6", + "type": "registry:block", + "title": "Hero 6", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-6.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-7", + "type": "registry:block", + "title": "Hero 7", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-7.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-8", + "type": "registry:block", + "title": "Hero 8", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-8.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "hero-9", + "type": "registry:block", + "title": "Hero 9", + "description": "Hero sections for launches, product storytelling, editorial pages, and social proof.", + "categories": [ + "hero" + ], + "docs": "https://ui.full.dev/react/blocks/hero/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/hero-9.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "links-2", + "type": "registry:block", + "title": "Links 2", + "description": "Link grid blocks for presenting related pages, components, or resources.", + "categories": [ + "links" + ], + "docs": "https://ui.full.dev/react/blocks/links/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/links-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "logos-1", + "type": "registry:block", + "title": "Logos 1", + "description": "Logo sections for trust, partner strips, and quiet social proof.", + "categories": [ + "logos" + ], + "docs": "https://ui.full.dev/react/blocks/logos/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/logo", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/logos-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "logos-2", + "type": "registry:block", + "title": "Logos 2", + "description": "Logo sections for trust, partner strips, and quiet social proof.", + "categories": [ + "logos" + ], + "docs": "https://ui.full.dev/react/blocks/logos/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/logo", + "@fulldev/marquee", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/logos-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "logos-3", + "type": "registry:block", + "title": "Logos 3", + "description": "Logo sections for trust, partner strips, and quiet social proof.", + "categories": [ + "logos" + ], + "docs": "https://ui.full.dev/react/blocks/logos/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/logo", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/logos-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "pricing-1", + "type": "registry:block", + "title": "Pricing 1", + "description": "Pricing sections for plan grids, featured offers, and concise offer presentation.", + "categories": [ + "pricing" + ], + "docs": "https://ui.full.dev/react/blocks/pricing/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/pricing-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "pricing-2", + "type": "registry:block", + "title": "Pricing 2", + "description": "Pricing sections for plan grids, featured offers, and concise offer presentation.", + "categories": [ + "pricing" + ], + "docs": "https://ui.full.dev/react/blocks/pricing/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/pricing-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "pricing-3", + "type": "registry:block", + "title": "Pricing 3", + "description": "Pricing sections for plan grids, featured offers, and concise offer presentation.", + "categories": [ + "pricing" + ], + "docs": "https://ui.full.dev/react/blocks/pricing/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/pricing-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "product-1", + "type": "registry:block", + "title": "Product 1", + "description": "A focused product section for flagship offers and compact product storytelling.", + "categories": [ + "product" + ], + "docs": "https://ui.full.dev/react/blocks/product/", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/price", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/product-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "products-1", + "type": "registry:block", + "title": "Products 1", + "description": "Product collection layouts for bundles, grouped offers, and category-led merchandising.", + "categories": [ + "products" + ], + "docs": "https://ui.full.dev/react/blocks/products/", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/products-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "products-2", + "type": "registry:block", + "title": "Products 2", + "description": "Product collection layouts for bundles, grouped offers, and category-led merchandising.", + "categories": [ + "products" + ], + "docs": "https://ui.full.dev/react/blocks/products/", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/price", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/products-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "products-3", + "type": "registry:block", + "title": "Products 3", + "description": "Product collection layouts for bundles, grouped offers, and category-led merchandising.", + "categories": [ + "products" + ], + "docs": "https://ui.full.dev/react/blocks/products/", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/products-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "products-4", + "type": "registry:block", + "title": "Products 4", + "description": "Product collection layouts for bundles, grouped offers, and category-led merchandising.", + "categories": [ + "products" + ], + "docs": "https://ui.full.dev/react/blocks/products/", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/products-4.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "products-5", + "type": "registry:block", + "title": "Products 5", + "description": "Product collection layouts for bundles, grouped offers, and category-led merchandising.", + "categories": [ + "products" + ], + "docs": "https://ui.full.dev/react/blocks/products/", + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/card", + "@fulldev/price", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/products-5.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "reviews-1", + "type": "registry:block", + "title": "Reviews 1", + "description": "Testimonial and review sections for social proof, trust, and product validation.", + "categories": [ + "reviews" + ], + "docs": "https://ui.full.dev/react/blocks/reviews/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/card", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/reviews-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "reviews-2", + "type": "registry:block", + "title": "Reviews 2", + "description": "Testimonial and review sections for social proof, trust, and product validation.", + "categories": [ + "reviews" + ], + "docs": "https://ui.full.dev/react/blocks/reviews/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/rating", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/reviews-2.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "reviews-3", + "type": "registry:block", + "title": "Reviews 3", + "description": "Testimonial and review sections for social proof, trust, and product validation.", + "categories": [ + "reviews" + ], + "docs": "https://ui.full.dev/react/blocks/reviews/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/carousel", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/reviews-3.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "reviews-4", + "type": "registry:block", + "title": "Reviews 4", + "description": "Testimonial and review sections for social proof, trust, and product validation.", + "categories": [ + "reviews" + ], + "docs": "https://ui.full.dev/react/blocks/reviews/", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/card", + "@fulldev/marquee", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/reviews-4.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "reviews-5", + "type": "registry:block", + "title": "Reviews 5", + "description": "Testimonial and review sections for social proof, trust, and product validation.", + "categories": [ + "reviews" + ], + "docs": "https://ui.full.dev/react/blocks/reviews/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/marquee", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/reviews-5.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "services-1", + "type": "registry:block", + "title": "Services 1", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "categories": [ + "services" + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-1.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "services-2", + "type": "registry:block", + "title": "Services 2", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "categories": [ + "services" + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-2.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "services-3", + "type": "registry:block", + "title": "Services 3", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "categories": [ + "services" + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-3.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "services-4", + "type": "registry:block", + "title": "Services 4", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "categories": [ + "services" + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-4.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "services-5", + "type": "registry:block", + "title": "Services 5", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "categories": [ + "services" + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-5.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "services-6", + "type": "registry:block", + "title": "Services 6", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "categories": [ + "services" + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-6.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "services-7", + "type": "registry:block", + "title": "Services 7", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "categories": [ + "services" + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-7.tsx", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "sidebar-1", + "type": "registry:block", + "title": "Sidebar 1", + "categories": [ + "sidebar" + ], + "docs": "https://ui.full.dev/react/blocks/sidebar/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/breadcrumb", + "@fulldev/button", + "@fulldev/command", + "@fulldev/dropdown-menu", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/kbd", + "@fulldev/logo", + "@fulldev/separator", + "@fulldev/sidebar", + "@fulldev/theme-toggle" + ], + "files": [ + { + "path": "src/components/blocks/sidebar-1.tsx", + "type": "registry:block" + } + ] + }, + { + "name": "accordion-examples", + "type": "registry:example", + "title": "Accordion examples", + "description": "The examples from the shadcn/ui Accordion docs.", + "docs": "https://ui.full.dev/react/components/accordion/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/accordion", + "@fulldev/card", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/accordion/accordion-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-borders.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-card.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-multiple.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/accordion/accordion-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "alert-examples", + "type": "registry:example", + "title": "Alert examples", + "description": "The examples from the shadcn/ui Alert docs.", + "docs": "https://ui.full.dev/react/components/alert/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/alert", + "@fulldev/button", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/alert/alert-action.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-colors.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-destructive.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert/alert-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "alert-dialog-examples", + "type": "registry:example", + "title": "Alert Dialog examples", + "description": "The examples from the shadcn/ui Alert Dialog docs.", + "docs": "https://ui.full.dev/react/components/alert-dialog/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/alert-dialog", + "@fulldev/button", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/alert-dialog/alert-dialog-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-destructive.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-media.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-small-media.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/alert-dialog/alert-dialog-small.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "aspect-ratio-examples", + "type": "registry:example", + "title": "Aspect Ratio examples", + "description": "The examples from the shadcn/ui Aspect Ratio docs.", + "docs": "https://ui.full.dev/react/components/aspect-ratio/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/aspect-ratio", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-portrait.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/aspect-ratio/aspect-ratio-square.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "attachment-examples", + "type": "registry:example", + "title": "Attachment examples", + "description": "The examples from the shadcn/ui Attachment docs.", + "docs": "https://ui.full.dev/react/components/attachment/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/attachment", + "@fulldev/dialog", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/attachment/attachment-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-image.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-sizes.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-states.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/attachment/attachment-trigger.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "avatar-examples", + "type": "registry:example", + "title": "Avatar examples", + "description": "The examples from the shadcn/ui Avatar docs.", + "docs": "https://ui.full.dev/react/components/avatar/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/avatar/avatar-badge-icon.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-badge.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-dropdown.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-group-count-icon.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-group-count.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/avatar/avatar-size.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "badge-examples", + "type": "registry:example", + "title": "Badge examples", + "description": "The examples from the shadcn/ui Badge docs.", + "docs": "https://ui.full.dev/react/components/badge/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/select", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/badge/badge-colors.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-icon.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-link.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-spinner.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/badge/badge-variants.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "breadcrumb-examples", + "type": "registry:example", + "title": "Breadcrumb examples", + "description": "The examples from the shadcn/ui Breadcrumb docs.", + "docs": "https://ui.full.dev/react/components/breadcrumb/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/breadcrumb", + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/breadcrumb/breadcrumb-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-dropdown.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-ellipsis.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-link.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/breadcrumb/breadcrumb-separator.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "bubble-examples", + "type": "registry:example", + "title": "Bubble examples", + "description": "The examples from the shadcn/ui Bubble docs.", + "docs": "https://ui.full.dev/react/components/bubble/", + "dependencies": [ + "@streamdown/code", + "cn", + "lucide-react", + "sonner", + "streamdown" + ], + "registryDependencies": [ + "@fulldev/bubble", + "@fulldev/button", + "@fulldev/collapsible", + "@fulldev/popover", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/bubble/bubble-alignment.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-collapsible.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-group-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-link-button.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-popover.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-reactions.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-tooltip.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/bubble/bubble-variants.tsx", + "type": "registry:component" + }, + { + "path": "src/components/markdown.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "button-examples", + "type": "registry:example", + "title": "Button examples", + "description": "The examples from the shadcn/ui Button docs.", + "docs": "https://ui.full.dev/react/components/button/", + "dependencies": [ + "@tabler/icons-react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/select", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/button/button-default.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-destructive.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-ghost.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-icon.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-link.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-outline.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-render.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-rounded.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-secondary.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-size.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-spinner.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button/button-with-icon.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "button-group-examples", + "type": "registry:example", + "title": "Button Group examples", + "description": "The examples from the shadcn/ui Button Group docs.", + "docs": "https://ui.full.dev/react/components/button-group/", + "dependencies": [ + "@tabler/icons-react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/button-group", + "@fulldev/dropdown-menu", + "@fulldev/field", + "@fulldev/input", + "@fulldev/input-group", + "@fulldev/popover", + "@fulldev/select", + "@fulldev/textarea", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/button-group/button-group-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-dropdown.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-input-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-input.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-nested.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-orientation.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-popover.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-select.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-separator.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-size.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/button-group/button-group-split.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "calendar-examples", + "type": "registry:example", + "title": "Calendar examples", + "description": "The examples from the shadcn/ui Calendar docs.", + "docs": "https://ui.full.dev/react/components/calendar/", + "dependencies": [ + "@daypicker/persian@10.0.2", + "@fontsource-variable/vazirmatn", + "cn", + "date-fns", + "lucide-react", + "react-day-picker" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/calendar", + "@fulldev/card", + "@fulldev/field", + "@fulldev/input-group", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/calendar/calendar-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-booked-dates.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-caption.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-custom-days.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-hijri.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-presets.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-range.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-time.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/calendar/calendar-week-numbers.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "card-examples", + "type": "registry:example", + "title": "Card examples", + "description": "The examples from the shadcn/ui Card docs.", + "docs": "https://ui.full.dev/react/components/card/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/card", + "@fulldev/input", + "@fulldev/label", + "@fulldev/select", + "@fulldev/toggle-group" + ], + "files": [ + { + "path": "src/components/examples/card/card-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/card/card-edge-to-edge.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/card/card-image.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/card/card-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/card/card-small.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/card/card-spacing.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "carousel-examples", + "type": "registry:example", + "title": "Carousel examples", + "description": "The examples from the shadcn/ui Carousel docs.", + "docs": "https://ui.full.dev/react/components/carousel/", + "dependencies": [ + "cn", + "embla-carousel-autoplay@8.6.0" + ], + "registryDependencies": [ + "@fulldev/card", + "@fulldev/carousel", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/carousel/carousel-api.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-orientation.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-plugin.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-size.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/carousel/carousel-spacing.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "chart-examples", + "type": "registry:example", + "title": "Chart examples", + "description": "The examples from the shadcn/ui Chart docs.", + "docs": "https://ui.full.dev/react/components/chart/", + "dependencies": [ + "cn", + "recharts@3.8.0" + ], + "registryDependencies": [ + "@fulldev/card", + "@fulldev/chart", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/chart/chart-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-example-axis.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-example-grid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-example-legend.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-example-tooltip.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-example.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/chart/chart-tooltip.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "checkbox-examples", + "type": "registry:example", + "title": "Checkbox examples", + "description": "The examples from the shadcn/ui Checkbox docs.", + "docs": "https://ui.full.dev/react/components/checkbox/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/checkbox", + "@fulldev/field", + "@fulldev/label", + "@fulldev/select", + "@fulldev/table" + ], + "files": [ + { + "path": "src/components/examples/checkbox/checkbox-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-description.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-invalid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/checkbox/checkbox-table.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "collapsible-examples", + "type": "registry:example", + "title": "Collapsible examples", + "description": "The examples from the shadcn/ui Collapsible docs.", + "docs": "https://ui.full.dev/react/components/collapsible/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/collapsible", + "@fulldev/field", + "@fulldev/input", + "@fulldev/select", + "@fulldev/tabs" + ], + "files": [ + { + "path": "src/components/examples/collapsible/collapsible-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/collapsible/collapsible-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/collapsible/collapsible-file-tree.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/collapsible/collapsible-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/collapsible/collapsible-settings.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "combobox-examples", + "type": "registry:example", + "title": "Combobox examples", + "description": "The examples from the shadcn/ui Combobox docs.", + "docs": "https://ui.full.dev/react/components/combobox/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/combobox", + "@fulldev/field", + "@fulldev/input-group", + "@fulldev/item", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/combobox/combobox-auto-highlight.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-clear.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-custom.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-groups.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-input-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-invalid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-multiple.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-popup.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/combobox/combobox-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "command-examples", + "type": "registry:example", + "title": "Command examples", + "description": "The examples from the shadcn/ui Command docs.", + "docs": "https://ui.full.dev/react/components/command/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/command", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/command/command-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/command/command-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/command/command-groups.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/command/command-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/command/command-scrollable.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/command/command-shortcuts.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "context-menu-examples", + "type": "registry:example", + "title": "Context Menu examples", + "description": "The examples from the shadcn/ui Context Menu docs.", + "docs": "https://ui.full.dev/react/components/context-menu/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/context-menu", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/context-menu/context-menu-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/context-menu/context-menu-checkboxes.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/context-menu/context-menu-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/context-menu/context-menu-destructive.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/context-menu/context-menu-groups.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/context-menu/context-menu-icons.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/context-menu/context-menu-radio.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/context-menu/context-menu-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/context-menu/context-menu-shortcuts.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/context-menu/context-menu-sides.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/context-menu/context-menu-submenu.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "data-table-examples", + "type": "registry:example", + "title": "Data Table examples", + "description": "The examples from the shadcn/ui Data Table docs.", + "docs": "https://ui.full.dev/react/components/data-table/", + "dependencies": [ + "@tanstack/react-table", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/checkbox", + "@fulldev/dropdown-menu", + "@fulldev/input", + "@fulldev/select", + "@fulldev/table" + ], + "files": [ + { + "path": "src/components/examples/data-table/data-table-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/data-table/data-table-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "date-picker-examples", + "type": "registry:example", + "title": "Date Picker examples", + "description": "The examples from the shadcn/ui Date Picker docs.", + "docs": "https://ui.full.dev/react/components/date-picker/", + "dependencies": [ + "chrono-node", + "cn", + "date-fns", + "lucide-react", + "react-day-picker" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/calendar", + "@fulldev/field", + "@fulldev/input", + "@fulldev/input-group", + "@fulldev/popover", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/date-picker/date-picker-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-dob.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-input.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-natural-language.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-range.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/date-picker/date-picker-time.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "dialog-examples", + "type": "registry:example", + "title": "Dialog examples", + "description": "The examples from the shadcn/ui Dialog docs.", + "docs": "https://ui.full.dev/react/components/dialog/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/dialog", + "@fulldev/field", + "@fulldev/input", + "@fulldev/label", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/dialog/dialog-close-button.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dialog/dialog-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dialog/dialog-no-close-button.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dialog/dialog-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dialog/dialog-scrollable-content.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dialog/dialog-sticky-footer.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "drawer-examples", + "type": "registry:example", + "title": "Drawer examples", + "description": "The examples from the shadcn/ui Drawer docs.", + "docs": "https://ui.full.dev/react/components/drawer/", + "dependencies": [ + "cn", + "sonner" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/dialog", + "@fulldev/drawer", + "@fulldev/field", + "@fulldev/input", + "@fulldev/label", + "@fulldev/radio-group", + "@fulldev/use-mobile" + ], + "files": [ + { + "path": "src/components/examples/drawer/drawer-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-dialog.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-nested.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-non-modal.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-sides.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-snap-points.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/drawer/drawer-swipe-handle.tsx", + "type": "registry:component" + }, + { + "path": "src/hooks/use-media-query.tsx", + "type": "registry:hook" + } + ] + }, + { + "name": "dropdown-menu-examples", + "type": "registry:example", + "title": "Dropdown Menu examples", + "description": "The examples from the shadcn/ui Dropdown Menu docs.", + "docs": "https://ui.full.dev/react/components/dropdown-menu/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-avatar.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-checkboxes-icons.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-checkboxes.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-complex.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-destructive.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-icons.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-radio-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-radio-icons.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-shortcuts.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/dropdown-menu/dropdown-menu-submenu.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "empty-examples", + "type": "registry:example", + "title": "Empty examples", + "description": "The examples from the shadcn/ui Empty docs.", + "docs": "https://ui.full.dev/react/components/empty/", + "dependencies": [ + "@tabler/icons-react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/empty", + "@fulldev/input-group", + "@fulldev/kbd", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/empty/empty-avatar-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-avatar.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-background.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-input-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-outline.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/empty/empty-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "field-examples", + "type": "registry:example", + "title": "Field examples", + "description": "The examples from the shadcn/ui Field docs.", + "docs": "https://ui.full.dev/react/components/field/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/checkbox", + "@fulldev/field", + "@fulldev/input", + "@fulldev/radio-group", + "@fulldev/select", + "@fulldev/slider", + "@fulldev/switch", + "@fulldev/textarea" + ], + "files": [ + { + "path": "src/components/examples/field/field-checkbox.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-choice-card.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-fieldset.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-input.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-radio.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-responsive.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-select.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-slider.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-switch.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/field/field-textarea.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "hover-card-examples", + "type": "registry:example", + "title": "Hover Card examples", + "description": "The examples from the shadcn/ui Hover Card docs.", + "docs": "https://ui.full.dev/react/components/hover-card/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/hover-card", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/hover-card/hover-card-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/hover-card/hover-card-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/hover-card/hover-card-sides.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "input-examples", + "type": "registry:example", + "title": "Input examples", + "description": "The examples from the shadcn/ui Input docs.", + "docs": "https://ui.full.dev/react/components/input/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/button-group", + "@fulldev/field", + "@fulldev/input", + "@fulldev/input-group", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/input/input-badge.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-button-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-field.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-fieldgroup.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-file.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-form.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-grid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-inline.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-input-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-invalid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-required.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input/input-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "input-group-examples", + "type": "registry:example", + "title": "Input Group examples", + "description": "The examples from the shadcn/ui Input Group docs.", + "docs": "https://ui.full.dev/react/components/input-group/", + "dependencies": [ + "@tabler/icons-react", + "cn", + "lucide-react", + "react-textarea-autosize" + ], + "registryDependencies": [ + "@fulldev/dropdown-menu", + "@fulldev/field", + "@fulldev/input-group", + "@fulldev/kbd", + "@fulldev/popover", + "@fulldev/select", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/input-group/input-group-block-end.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-block-start.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-button.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-custom.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-dropdown.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-icon.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-inline-end.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-inline-start.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-kbd.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-spinner.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-text.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-group/input-group-textarea.tsx", + "type": "registry:component" + }, + { + "path": "src/hooks/use-copy-to-clipboard.ts", + "type": "registry:hook" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "input-otp-examples", + "type": "registry:example", + "title": "Input Otp examples", + "description": "The examples from the shadcn/ui Input Otp docs.", + "docs": "https://ui.full.dev/react/components/input-otp/", + "dependencies": [ + "cn", + "input-otp", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/field", + "@fulldev/input-otp", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/input-otp/input-otp-alphanumeric.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-controlled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-form.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-four-digits.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-invalid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-pattern.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/input-otp/input-otp-separator.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "item-examples", + "type": "registry:example", + "title": "Item examples", + "description": "The examples from the shadcn/ui Item docs.", + "docs": "https://ui.full.dev/react/components/item/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/item", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/item/item-avatar.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-dropdown.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-header.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-icon.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-image.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-link.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-size.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/item/item-variant.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "kbd-examples", + "type": "registry:example", + "title": "Kbd examples", + "description": "The examples from the shadcn/ui Kbd docs.", + "docs": "https://ui.full.dev/react/components/kbd/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/button-group", + "@fulldev/input-group", + "@fulldev/kbd", + "@fulldev/select", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/kbd/kbd-button.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-input-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/kbd/kbd-tooltip.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "label-examples", + "type": "registry:example", + "title": "Label examples", + "description": "The examples from the shadcn/ui Label docs.", + "docs": "https://ui.full.dev/react/components/label/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/checkbox", + "@fulldev/label", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/label/label-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/label/label-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "marker-examples", + "type": "registry:example", + "title": "Marker examples", + "description": "The examples from the shadcn/ui Marker docs.", + "docs": "https://ui.full.dev/react/components/marker/", + "dependencies": [ + "lucide-react", + "sonner" + ], + "registryDependencies": [ + "@fulldev/marker", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/marker/marker-border.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-icon.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-link-button.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-separator.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-shimmer.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-status.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/marker/marker-variants.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "menubar-examples", + "type": "registry:example", + "title": "Menubar examples", + "description": "The examples from the shadcn/ui Menubar docs.", + "docs": "https://ui.full.dev/react/components/menubar/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/menubar", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/menubar/menubar-checkbox.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/menubar/menubar-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/menubar/menubar-icons.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/menubar/menubar-radio.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/menubar/menubar-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/menubar/menubar-submenu.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "message-examples", + "type": "registry:example", + "title": "Message examples", + "description": "The examples from the shadcn/ui Message docs.", + "docs": "https://ui.full.dev/react/components/message/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/attachment", + "@fulldev/avatar", + "@fulldev/bubble", + "@fulldev/button", + "@fulldev/marker", + "@fulldev/message" + ], + "files": [ + { + "path": "src/components/examples/message/message-actions.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message/message-attachment.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message/message-avatar.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message/message-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message/message-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message/message-header-footer.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "message-scroller-examples", + "type": "registry:example", + "title": "Message Scroller examples", + "description": "The examples from the shadcn/ui Message Scroller docs.", + "docs": "https://ui.full.dev/react/components/message-scroller/", + "dependencies": [ + "@ai-sdk/react", + "@shadcn/helpers", + "ai", + "lucide-react", + "motion", + "sonner" + ], + "registryDependencies": [ + "@fulldev/bubble", + "@fulldev/button", + "@fulldev/card", + "@fulldev/dropdown-menu", + "@fulldev/empty", + "@fulldev/hover-card", + "@fulldev/input-group", + "@fulldev/marker", + "@fulldev/message", + "@fulldev/message-scroller", + "@fulldev/select", + "@fulldev/slider", + "@fulldev/tabs", + "@fulldev/toggle-group", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/message-scroller/message-scroller-anchoring.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-animation.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-commands.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-group-chat.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-load-history.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-opening-position.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-previous-context.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-scrollable.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-streaming.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/message-scroller/message-scroller-visibility.tsx", + "type": "registry:component" + }, + { + "path": "src/components/message-animated.tsx", + "type": "registry:component" + }, + { + "path": "src/lib/ai.ts", + "type": "registry:lib" + }, + { + "path": "src/lib/message-animations.ts", + "type": "registry:lib" + } + ] + }, + { + "name": "native-select-examples", + "type": "registry:example", + "title": "Native Select examples", + "description": "The examples from the shadcn/ui Native Select docs.", + "docs": "https://ui.full.dev/react/components/native-select/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/native-select", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/native-select/native-select-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-groups.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-invalid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/native-select/native-select-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "navigation-menu-examples", + "type": "registry:example", + "title": "Navigation Menu examples", + "description": "The examples from the shadcn/ui Navigation Menu docs.", + "docs": "https://ui.full.dev/react/components/navigation-menu/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/navigation-menu", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/navigation-menu/navigation-menu-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/navigation-menu/navigation-menu-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "pagination-examples", + "type": "registry:example", + "title": "Pagination examples", + "description": "The examples from the shadcn/ui Pagination docs.", + "docs": "https://ui.full.dev/react/components/pagination/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/field", + "@fulldev/pagination", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/pagination/pagination-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/pagination/pagination-icons-only.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/pagination/pagination-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/pagination/pagination-simple.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "popover-examples", + "type": "registry:example", + "title": "Popover examples", + "description": "The examples from the shadcn/ui Popover docs.", + "docs": "https://ui.full.dev/react/components/popover/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/field", + "@fulldev/input", + "@fulldev/label", + "@fulldev/popover", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/popover/popover-alignments.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-basic.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-form.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/popover/popover-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "progress-examples", + "type": "registry:example", + "title": "Progress examples", + "description": "The examples from the shadcn/ui Progress docs.", + "docs": "https://ui.full.dev/react/components/progress/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/progress", + "@fulldev/select", + "@fulldev/slider" + ], + "files": [ + { + "path": "src/components/examples/progress/progress-controlled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/progress/progress-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/progress/progress-label.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/progress/progress-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "questionnaire-examples", + "type": "registry:example", + "title": "Questionnaire examples", + "description": "The examples from the shadcn/ui Questionnaire docs.", + "docs": "https://ui.full.dev/react/components/questionnaire/", + "dependencies": [ + "@shadcn/react", + "sonner", + "zod" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/card", + "@fulldev/dialog", + "@fulldev/native-select", + "@fulldev/questionnaire" + ], + "files": [ + { + "path": "src/components/examples/questionnaire/questionnaire-animated.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-card.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-conditional.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-controlled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-dialog.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-freeform.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-multiple.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-navigation-state.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-progress.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-resume.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-shortcuts.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-skip.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/questionnaire/questionnaire-validation.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "radio-group-examples", + "type": "registry:example", + "title": "Radio Group examples", + "description": "The examples from the shadcn/ui Radio Group docs.", + "docs": "https://ui.full.dev/react/components/radio-group/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/field", + "@fulldev/label", + "@fulldev/radio-group", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/radio-group/radio-group-choice-card.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-description.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-fieldset.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-invalid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/radio-group/radio-group-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "resizable-examples", + "type": "registry:example", + "title": "Resizable examples", + "description": "The examples from the shadcn/ui Resizable docs.", + "docs": "https://ui.full.dev/react/components/resizable/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/resizable", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/resizable/resizable-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/resizable/resizable-handle.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/resizable/resizable-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/resizable/resizable-vertical.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "scroll-area-examples", + "type": "registry:example", + "title": "Scroll Area examples", + "description": "The examples from the shadcn/ui Scroll Area docs.", + "docs": "https://ui.full.dev/react/components/scroll-area/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/scroll-area", + "@fulldev/select", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/examples/scroll-area/scroll-area-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/scroll-area/scroll-area-horizontal-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/scroll-area/scroll-area-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "select-examples", + "type": "registry:example", + "title": "Select examples", + "description": "The examples from the shadcn/ui Select docs.", + "docs": "https://ui.full.dev/react/components/select/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/field", + "@fulldev/label", + "@fulldev/select", + "@fulldev/switch" + ], + "files": [ + { + "path": "src/components/examples/select/select-align-item.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-groups.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-invalid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-scrollable.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "separator-examples", + "type": "registry:example", + "title": "Separator examples", + "description": "The examples from the shadcn/ui Separator docs.", + "docs": "https://ui.full.dev/react/components/separator/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/select", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/examples/separator/separator-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/separator/separator-list.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/separator/separator-menu.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/separator/separator-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/separator/separator-vertical.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "sheet-examples", + "type": "registry:example", + "title": "Sheet examples", + "description": "The examples from the shadcn/ui Sheet docs.", + "docs": "https://ui.full.dev/react/components/sheet/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/field", + "@fulldev/input", + "@fulldev/label", + "@fulldev/select", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/examples/sheet/sheet-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/sheet/sheet-no-close-button.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/sheet/sheet-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/sheet/sheet-side.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "sidebar-examples", + "type": "registry:example", + "title": "Sidebar examples", + "description": "The examples from the shadcn/ui Sidebar docs.", + "docs": "https://ui.full.dev/react/components/sidebar/", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/collapsible", + "@fulldev/dropdown-menu", + "@fulldev/sidebar" + ], + "files": [ + { + "path": "src/components/examples/sidebar/sidebar-demo.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "skeleton-examples", + "type": "registry:example", + "title": "Skeleton examples", + "description": "The examples from the shadcn/ui Skeleton docs.", + "docs": "https://ui.full.dev/react/components/skeleton/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/card", + "@fulldev/select", + "@fulldev/skeleton" + ], + "files": [ + { + "path": "src/components/examples/skeleton/skeleton-avatar.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/skeleton/skeleton-card.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/skeleton/skeleton-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/skeleton/skeleton-form.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/skeleton/skeleton-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/skeleton/skeleton-table.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/skeleton/skeleton-text.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "slider-examples", + "type": "registry:example", + "title": "Slider examples", + "description": "The examples from the shadcn/ui Slider docs.", + "docs": "https://ui.full.dev/react/components/slider/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/label", + "@fulldev/select", + "@fulldev/slider" + ], + "files": [ + { + "path": "src/components/examples/slider/slider-controlled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/slider/slider-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/slider/slider-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/slider/slider-multiple.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/slider/slider-range.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/slider/slider-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/slider/slider-vertical.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "spinner-examples", + "type": "registry:example", + "title": "Spinner examples", + "description": "The examples from the shadcn/ui Spinner docs.", + "docs": "https://ui.full.dev/react/components/spinner/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/empty", + "@fulldev/input-group", + "@fulldev/item", + "@fulldev/select", + "@fulldev/spinner" + ], + "files": [ + { + "path": "src/components/examples/spinner/spinner-badge.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/spinner/spinner-button.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/spinner/spinner-custom.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/spinner/spinner-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/spinner/spinner-empty.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/spinner/spinner-input-group.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/spinner/spinner-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/spinner/spinner-size.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "switch-examples", + "type": "registry:example", + "title": "Switch examples", + "description": "The examples from the shadcn/ui Switch docs.", + "docs": "https://ui.full.dev/react/components/switch/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/field", + "@fulldev/label", + "@fulldev/select", + "@fulldev/switch" + ], + "files": [ + { + "path": "src/components/examples/switch/switch-choice-card.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/switch/switch-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/switch/switch-description.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/switch/switch-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/switch/switch-invalid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/switch/switch-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/switch/switch-sizes.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "table-examples", + "type": "registry:example", + "title": "Table examples", + "description": "The examples from the shadcn/ui Table docs.", + "docs": "https://ui.full.dev/react/components/table/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/dropdown-menu", + "@fulldev/select", + "@fulldev/table" + ], + "files": [ + { + "path": "src/components/examples/table/table-actions.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/table/table-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/table/table-footer.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/table/table-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "tabs-examples", + "type": "registry:example", + "title": "Tabs examples", + "description": "The examples from the shadcn/ui Tabs docs.", + "docs": "https://ui.full.dev/react/components/tabs/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/card", + "@fulldev/select", + "@fulldev/tabs" + ], + "files": [ + { + "path": "src/components/examples/tabs/tabs-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/tabs/tabs-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/tabs/tabs-icons.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/tabs/tabs-line.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/tabs/tabs-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/tabs/tabs-vertical.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "textarea-examples", + "type": "registry:example", + "title": "Textarea examples", + "description": "The examples from the shadcn/ui Textarea docs.", + "docs": "https://ui.full.dev/react/components/textarea/", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/field", + "@fulldev/select", + "@fulldev/textarea" + ], + "files": [ + { + "path": "src/components/examples/textarea/textarea-button.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/textarea/textarea-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/textarea/textarea-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/textarea/textarea-field.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/textarea/textarea-invalid.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/textarea/textarea-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "toast-examples", + "type": "registry:example", + "title": "Toast examples", + "description": "The examples from the shadcn/ui Toast docs.", + "docs": "https://ui.full.dev/react/components/toast/", + "registryDependencies": [ + "@fulldev/button", + "@fulldev/toast" + ], + "files": [ + { + "path": "src/components/examples/toast/toast-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toast/toast-promise.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toast/toast-types.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "toggle-examples", + "type": "registry:example", + "title": "Toggle examples", + "description": "The examples from the shadcn/ui Toggle docs.", + "docs": "https://ui.full.dev/react/components/toggle/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/select", + "@fulldev/toggle" + ], + "files": [ + { + "path": "src/components/examples/toggle/toggle-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle/toggle-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle/toggle-outline.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle/toggle-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle/toggle-sizes.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle/toggle-text.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "toggle-group-examples", + "type": "registry:example", + "title": "Toggle Group examples", + "description": "The examples from the shadcn/ui Toggle Group docs.", + "docs": "https://ui.full.dev/react/components/toggle-group/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/field", + "@fulldev/select", + "@fulldev/toggle-group" + ], + "files": [ + { + "path": "src/components/examples/toggle-group/toggle-group-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle-group/toggle-group-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle-group/toggle-group-font-weight-selector.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle-group/toggle-group-outline.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle-group/toggle-group-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle-group/toggle-group-sizes.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle-group/toggle-group-spacing.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/toggle-group/toggle-group-vertical.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + }, + { + "name": "tooltip-examples", + "type": "registry:example", + "title": "Tooltip examples", + "description": "The examples from the shadcn/ui Tooltip docs.", + "docs": "https://ui.full.dev/react/components/tooltip/", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/kbd", + "@fulldev/select", + "@fulldev/tooltip" + ], + "files": [ + { + "path": "src/components/examples/tooltip/tooltip-demo.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/tooltip/tooltip-disabled.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/tooltip/tooltip-keyboard.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/tooltip/tooltip-rtl.tsx", + "type": "registry:component" + }, + { + "path": "src/components/examples/tooltip/tooltip-sides.tsx", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "type": "registry:component" + } + ] + } + ] +} diff --git a/public/r/react/styles/base-luma/resizable-examples.json b/public/r/react/styles/base-luma/resizable-examples.json new file mode 100644 index 000000000..6f67b8074 --- /dev/null +++ b/public/r/react/styles/base-luma/resizable-examples.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "resizable-examples", + "title": "Resizable examples", + "description": "The examples from the shadcn/ui Resizable docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/resizable", + "@fulldev/select" + ], + "files": [ + { + "path": "src/components/examples/resizable/resizable-demo.tsx", + "content": "import {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from \"@/components/ui/resizable\"\n\nexport function ResizableDemo() {\n return (\n \n \n
    \n One\n
    \n
    \n \n \n \n \n
    \n Two\n
    \n
    \n \n \n
    \n Three\n
    \n
    \n
    \n
    \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/resizable/resizable-handle.tsx", + "content": "import {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from \"@/components/ui/resizable\"\n\nexport function ResizableHandleDemo() {\n return (\n \n \n
    \n Sidebar\n
    \n
    \n \n \n
    \n Content\n
    \n
    \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/resizable/resizable-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from \"@/components/ui/resizable\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n one: \"One\",\n two: \"Two\",\n three: \"Three\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n one: \"واحد\",\n two: \"اثنان\",\n three: \"ثلاثة\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n one: \"אחד\",\n two: \"שניים\",\n three: \"שלושה\",\n },\n },\n}\n\nexport function ResizableRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n \n \n
    \n {t.one}\n
    \n
    \n \n \n \n \n
    \n {t.two}\n
    \n
    \n \n \n
    \n {t.three}\n
    \n
    \n
    \n
    \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/resizable/resizable-vertical.tsx", + "content": "import {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from \"@/components/ui/resizable\"\n\nexport function ResizableVertical() {\n return (\n \n \n
    \n Header\n
    \n
    \n \n \n
    \n Content\n
    \n
    \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/resizable/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/resizable.json b/public/r/react/styles/base-luma/resizable.json new file mode 100644 index 000000000..fba56cf93 --- /dev/null +++ b/public/r/react/styles/base-luma/resizable.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "resizable", + "title": "Resizable", + "description": "Accessible panel groups with pointer and keyboard resizing.", + "dependencies": [ + "cn", + "react-resizable-panels" + ], + "files": [ + { + "path": "src/components/ui/resizable.tsx", + "content": "\"use client\"\n\nimport { cn } from \"cn\"\nimport * as ResizablePrimitive from \"react-resizable-panels\"\n\nfunction ResizablePanelGroup({\n className,\n ...props\n}: ResizablePrimitive.GroupProps) {\n return (\n \n )\n}\n\nfunction ResizablePanel({ ...props }: ResizablePrimitive.PanelProps) {\n return \n}\n\nfunction ResizableHandle({\n withHandle,\n className,\n ...props\n}: ResizablePrimitive.SeparatorProps & {\n withHandle?: boolean\n}) {\n return (\n div]:rotate-90\",\n className\n )}\n {...props}\n >\n {withHandle && (\n
    \n )}\n \n )\n}\n\nexport { ResizableHandle, ResizablePanel, ResizablePanelGroup }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/resizable/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/reviews-1.json b/public/r/react/styles/base-luma/reviews-1.json new file mode 100644 index 000000000..8a4ac684b --- /dev/null +++ b/public/r/react/styles/base-luma/reviews-1.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "reviews-1", + "title": "Reviews 1", + "description": "Testimonial and review sections for social proof, trust, and product validation.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/card", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/reviews-1.tsx", + "content": "import * as React from \"react\"\nimport { QuoteIcon } from \"lucide-react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport { Rating } from \"@/components/ui/rating\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Reviews1({\n title,\n description,\n reviews,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n reviews: {\n rating: number\n ratingLabel: string\n quote: string\n image?: string\n initials: string\n name: string\n role: string\n }[]\n}) {\n return (\n
    \n \n {title}\n \n {description}\n \n \n \n
    \n {reviews.map((item) => (\n \n \n
    \n
    \n \n \n
    \n
    \n

    {item.quote}

    \n
    \n
    \n \n \n {item.initials}\n \n
    \n

    \n {item.name}\n

    \n

    \n {item.role}\n

    \n
    \n
    \n
    \n
    \n
    \n ))}\n
    \n
    \n
    \n )\n}\n\nexport { Reviews1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/reviews/", + "categories": [ + "reviews" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/reviews-2.json b/public/r/react/styles/base-luma/reviews-2.json new file mode 100644 index 000000000..8f497f3cb --- /dev/null +++ b/public/r/react/styles/base-luma/reviews-2.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "reviews-2", + "title": "Reviews 2", + "description": "Testimonial and review sections for social proof, trust, and product validation.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/rating", + "@fulldev/section", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/blocks/reviews-2.tsx", + "content": "import * as React from \"react\"\nimport { QuoteIcon } from \"lucide-react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Rating } from \"@/components/ui/rating\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction Reviews2({\n featured,\n reviews,\n ...props\n}: React.ComponentProps<\"section\"> & {\n featured: {\n quote: string\n image?: string\n initials: string\n name: string\n role: string\n }\n reviews: {\n rating: number\n ratingLabel: string\n quote: string\n image?: string\n initials: string\n name: string\n role: string\n }[]\n}) {\n return (\n
    \n \n
    \n \n
    \n

    {featured.quote}

    \n
    \n
    \n \n \n {featured.initials}\n \n
    \n

    \n {featured.name}\n

    \n

    {featured.role}

    \n
    \n
    \n
    \n
    \n {reviews.map((item) => (\n
    \n \n
    \n \n
    \n

    {item.quote}

    \n
    \n
    \n \n \n {item.initials}\n \n
    \n

    \n {item.name}\n

    \n

    {item.role}

    \n
    \n
    \n
    \n
    \n ))}\n
    \n
    \n
    \n )\n}\n\nexport { Reviews2 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/reviews/", + "categories": [ + "reviews" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/reviews-3.json b/public/r/react/styles/base-luma/reviews-3.json new file mode 100644 index 000000000..8cb390ded --- /dev/null +++ b/public/r/react/styles/base-luma/reviews-3.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "reviews-3", + "title": "Reviews 3", + "description": "Testimonial and review sections for social proof, trust, and product validation.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/carousel", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/reviews-3.tsx", + "content": "import * as React from \"react\"\nimport { QuoteIcon } from \"lucide-react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\"\nimport { Rating } from \"@/components/ui/rating\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Reviews3({\n title,\n description,\n labels,\n reviews,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n labels: {\n previous: string\n next: string\n carousel: string\n slide: string\n }\n reviews: {\n rating: number\n ratingLabel: string\n quote: string\n image?: string\n initials: string\n name: string\n role: string\n }[]\n}) {\n return (\n
    \n \n {title}\n \n {description}\n \n \n \n \n \n {reviews.map((item) => (\n \n
    \n \n \n
    \n

    {item.quote}

    \n
    \n
    \n \n \n {item.initials}\n \n
    \n

    \n {item.name}\n

    \n

    \n {item.role}\n

    \n
    \n
    \n
    \n \n ))}\n
    \n \n \n \n
    \n
    \n )\n}\n\nexport { Reviews3 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/reviews/", + "categories": [ + "reviews" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/reviews-4.json b/public/r/react/styles/base-luma/reviews-4.json new file mode 100644 index 000000000..c9fa503a1 --- /dev/null +++ b/public/r/react/styles/base-luma/reviews-4.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "reviews-4", + "title": "Reviews 4", + "description": "Testimonial and review sections for social proof, trust, and product validation.", + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/card", + "@fulldev/marquee", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/reviews-4.tsx", + "content": "import * as React from \"react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport {\n Marquee,\n MarqueeContent,\n MarqueeItem,\n MarqueeToggle,\n} from \"@/components/ui/marquee\"\nimport { Rating } from \"@/components/ui/rating\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Reviews4({\n title,\n description,\n labels,\n reviews,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n labels: {\n play: string\n pause: string\n }\n reviews: {\n rating: number\n ratingLabel: string\n quote: string\n image?: string\n initials: string\n name: string\n role: string\n }[]\n}) {\n const half = Math.ceil(reviews.length / 2)\n const rows = [reviews.slice(0, half), reviews.slice(half)]\n\n return (\n
    \n \n {title}\n \n {description}\n \n \n \n \n \n \n {rows\n .filter((row) => row.length > 0)\n .map((row, index) => (\n \n {row.map((item) => (\n \n \n \n
    \n \n
    \n

    {item.quote}

    \n
    \n
    \n \n \n {item.initials}\n \n
    \n

    \n {item.name}\n

    \n

    \n {item.role}\n

    \n
    \n
    \n
    \n
    \n
    \n
    \n ))}\n \n ))}\n
    \n
    \n )\n}\n\nexport { Reviews4 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/reviews/", + "categories": [ + "reviews" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/reviews-5.json b/public/r/react/styles/base-luma/reviews-5.json new file mode 100644 index 000000000..6913b8f3e --- /dev/null +++ b/public/r/react/styles/base-luma/reviews-5.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "reviews-5", + "title": "Reviews 5", + "description": "Testimonial and review sections for social proof, trust, and product validation.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/marquee", + "@fulldev/rating", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/reviews-5.tsx", + "content": "import * as React from \"react\"\nimport { QuoteIcon } from \"lucide-react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport {\n Marquee,\n MarqueeContent,\n MarqueeItem,\n MarqueeToggle,\n} from \"@/components/ui/marquee\"\nimport { Rating } from \"@/components/ui/rating\"\nimport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Reviews5({\n title,\n description,\n labels,\n reviews,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n labels: {\n play: string\n pause: string\n }\n reviews: {\n quote: string\n image?: string\n initials: string\n name: string\n role: string\n rating: number\n ratingLabel: string\n }[]\n}) {\n const third = Math.ceil(reviews.length / 3)\n const rows = [\n reviews.slice(0, third),\n reviews.slice(third, third * 2),\n reviews.slice(third * 2),\n ]\n\n return (\n
    \n \n {title}\n \n {description}\n \n \n \n \n \n \n {rows\n .filter((row) => row.length > 0)\n .map((row, index) => (\n \n {row.map((item) => (\n \n
    \n
    \n
    \n \n \n {item.initials}\n \n
    \n

    \n {item.name}\n

    \n

    \n {item.role}\n

    \n
    \n
    \n \n
    \n
    \n \n
    \n

    {item.quote}

    \n
    \n
    \n
    \n
    \n ))}\n \n ))}\n
    \n
    \n )\n}\n\nexport { Reviews5 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/reviews/", + "categories": [ + "reviews" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/scroll-area-examples.json b/public/r/react/styles/base-luma/scroll-area-examples.json new file mode 100644 index 000000000..fc26f55d6 --- /dev/null +++ b/public/r/react/styles/base-luma/scroll-area-examples.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "scroll-area-examples", + "title": "Scroll Area examples", + "description": "The examples from the shadcn/ui Scroll Area docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/scroll-area", + "@fulldev/select", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/examples/scroll-area/scroll-area-demo.tsx", + "content": "import * as React from \"react\"\n\nimport { ScrollArea } from \"@/components/ui/scroll-area\"\nimport { Separator } from \"@/components/ui/separator\"\n\nconst tags = Array.from({ length: 50 }).map(\n (_, i, a) => `v1.2.0-beta.${a.length - i}`\n)\n\nexport function ScrollAreaDemo() {\n return (\n \n
    \n

    Tags

    \n {tags.map((tag) => (\n \n
    {tag}
    \n \n
    \n ))}\n
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/scroll-area/scroll-area-horizontal-demo.tsx", + "content": "import * as React from \"react\"\n\nimport { ScrollArea, ScrollBar } from \"@/components/ui/scroll-area\"\n\nexport interface Artwork {\n artist: string\n art: string\n}\n\nexport const works: Artwork[] = [\n {\n artist: \"Ornella Binni\",\n art: \"https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80\",\n },\n {\n artist: \"Tom Byrom\",\n art: \"https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80\",\n },\n {\n artist: \"Vladimir Malyavko\",\n art: \"https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80\",\n },\n]\n\nexport function ScrollAreaHorizontalDemo() {\n return (\n \n
    \n {works.map((artwork) => (\n
    \n
    \n \n
    \n
    \n Photo by{\" \"}\n \n {artwork.artist}\n \n
    \n
    \n ))}\n
    \n \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/scroll-area/scroll-area-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { ScrollArea } from \"@/components/ui/scroll-area\"\nimport { Separator } from \"@/components/ui/separator\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst tags = Array.from({ length: 50 }).map(\n (_, i, a) => `v1.2.0-beta.${a.length - i}`\n)\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n tags: \"Tags\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n tags: \"العلامات\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n tags: \"תגיות\",\n },\n },\n}\n\nexport function ScrollAreaRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n \n
    \n

    {t.tags}

    \n {tags.map((tag) => (\n \n
    {tag}
    \n \n
    \n ))}\n
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/scroll-area/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/scroll-area.json b/public/r/react/styles/base-luma/scroll-area.json new file mode 100644 index 000000000..5c47befa5 --- /dev/null +++ b/public/r/react/styles/base-luma/scroll-area.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "scroll-area", + "title": "Scroll Area", + "description": "Native scrolling with custom, cross-browser scrollbars.", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/scroll-area.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ScrollArea as ScrollAreaPrimitive } from \"@base-ui/react/scroll-area\"\nimport { cn } from \"cn\"\n\nfunction ScrollArea({\n className,\n children,\n ...props\n}: ScrollAreaPrimitive.Root.Props) {\n return (\n \n \n {children}\n \n \n \n \n )\n}\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n ...props\n}: ScrollAreaPrimitive.Scrollbar.Props) {\n return (\n \n \n \n )\n}\n\nexport { ScrollArea, ScrollBar }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/scroll-area/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/section.json b/public/r/react/styles/base-luma/section.json new file mode 100644 index 000000000..a70b3d4af --- /dev/null +++ b/public/r/react/styles/base-luma/section.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "section", + "title": "Section", + "description": "A layout component for organizing page content into sections.", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn" + ], + "files": [ + { + "path": "src/components/ui/section.tsx", + "content": "import * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nconst sectionVariants = cva(\"gap-16 py-[var(--section-padding,--spacing(20))] relative flex scroll-mt-12 flex-col\", {\n variants: {\n variant: {\n default: \"w-full bg-background\",\n floating:\n \"my-20 rounded-4xl bg-background shadow-md ring-1 ring-foreground/5 dark:ring-foreground/10 mx-auto w-[calc(100%-2*var(--gutter,--spacing(4)))] max-w-[calc(var(--container,var(--container-7xl))-2*var(--gutter,--spacing(4)))] overflow-hidden\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n})\n\nfunction Section({\n className,\n variant = \"default\",\n ...props\n}: React.ComponentProps<\"section\"> & VariantProps) {\n return (\n \n )\n}\n\nfunction SectionContainer({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction SectionTitle({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"h2\">) {\n return useRender({\n defaultTagName: \"h2\",\n props: mergeProps<\"h2\">(\n {\n className: cn(\n \"text-3xl font-medium tracking-tight sm:text-4xl font-heading text-balance text-foreground\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"section-title\",\n },\n })\n}\n\nfunction SectionDescription({\n className,\n ...props\n}: React.ComponentProps<\"p\">) {\n return (\n \n )\n}\n\nexport {\n Section,\n SectionContainer,\n SectionDescription,\n SectionTitle,\n sectionVariants,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/section/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/select-examples.json b/public/r/react/styles/base-luma/select-examples.json new file mode 100644 index 000000000..5838e5e00 --- /dev/null +++ b/public/r/react/styles/base-luma/select-examples.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "select-examples", + "title": "Select examples", + "description": "The examples from the shadcn/ui Select docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/field", + "@fulldev/label", + "@fulldev/select", + "@fulldev/switch" + ], + "files": [ + { + "path": "src/components/examples/select/select-align-item.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Field,\n FieldContent,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n} from \"@/components/ui/field\"\nimport { Label } from \"@/components/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\nimport { Switch } from \"@/components/ui/switch\"\n\nconst items = [\n { label: \"Select a fruit\", value: null },\n { label: \"Apple\", value: \"apple\" },\n { label: \"Banana\", value: \"banana\" },\n { label: \"Blueberry\", value: \"blueberry\" },\n { label: \"Grapes\", value: \"grapes\" },\n { label: \"Pineapple\", value: \"pineapple\" },\n]\n\nexport function SelectAlignItem() {\n const [alignItemWithTrigger, setAlignItemWithTrigger] = React.useState(true)\n\n return (\n \n \n \n Align Item\n \n Toggle to align the item with the trigger.\n \n \n \n \n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-demo.tsx", + "content": "import {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nconst items = [\n { label: \"Select a fruit\", value: null },\n { label: \"Apple\", value: \"apple\" },\n { label: \"Banana\", value: \"banana\" },\n { label: \"Blueberry\", value: \"blueberry\" },\n { label: \"Grapes\", value: \"grapes\" },\n { label: \"Pineapple\", value: \"pineapple\" },\n]\n\nexport function SelectDemo() {\n return (\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-disabled.tsx", + "content": "import {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport function SelectDisabled() {\n const items = [\n { label: \"Select a fruit\", value: null },\n { label: \"Apple\", value: \"apple\" },\n { label: \"Banana\", value: \"banana\" },\n { label: \"Blueberry\", value: \"blueberry\" },\n { label: \"Grapes\", value: \"grapes\", disabled: true },\n { label: \"Pineapple\", value: \"pineapple\" },\n ]\n return (\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-groups.tsx", + "content": "import {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport function SelectGroups() {\n const fruits = [\n { label: \"Apple\", value: \"apple\" },\n { label: \"Banana\", value: \"banana\" },\n { label: \"Blueberry\", value: \"blueberry\" },\n ]\n const vegetables = [\n { label: \"Carrot\", value: \"carrot\" },\n { label: \"Broccoli\", value: \"broccoli\" },\n { label: \"Spinach\", value: \"spinach\" },\n ]\n const allItems = [\n { label: \"Select a fruit\", value: null },\n ...fruits,\n ...vegetables,\n ]\n return (\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-invalid.tsx", + "content": "import { Field, FieldError, FieldLabel } from \"@/components/ui/field\"\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nconst items = [\n { label: \"Select a fruit\", value: null },\n { label: \"Apple\", value: \"apple\" },\n { label: \"Banana\", value: \"banana\" },\n { label: \"Blueberry\", value: \"blueberry\" },\n]\n\nexport function SelectInvalid() {\n return (\n \n Fruit\n \n Please select a fruit.\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\nimport {\n useTranslation,\n type Language,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n selectFruit: \"Select a fruit\",\n fruits: \"Fruits\",\n apple: \"Apple\",\n banana: \"Banana\",\n blueberry: \"Blueberry\",\n grapes: \"Grapes\",\n pineapple: \"Pineapple\",\n vegetables: \"Vegetables\",\n carrot: \"Carrot\",\n broccoli: \"Broccoli\",\n spinach: \"Spinach\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n selectFruit: \"اختر فاكهة\",\n fruits: \"الفواكه\",\n apple: \"تفاح\",\n banana: \"موز\",\n blueberry: \"توت أزرق\",\n grapes: \"عنب\",\n pineapple: \"أناناس\",\n vegetables: \"الخضروات\",\n carrot: \"جزر\",\n broccoli: \"بروكلي\",\n spinach: \"سبانخ\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n selectFruit: \"בחר פרי\",\n fruits: \"פירות\",\n apple: \"תפוח\",\n banana: \"בננה\",\n blueberry: \"אוכמניה\",\n grapes: \"ענבים\",\n pineapple: \"אננס\",\n vegetables: \"ירקות\",\n carrot: \"גזר\",\n broccoli: \"ברוקולי\",\n spinach: \"תרד\",\n },\n },\n}\n\nexport function SelectRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n const [selectedFruit, setSelectedFruit] = React.useState(null)\n\n const fruits = [\n { label: t.apple, value: \"apple\" },\n { label: t.banana, value: \"banana\" },\n { label: t.blueberry, value: \"blueberry\" },\n { label: t.grapes, value: \"grapes\" },\n { label: t.pineapple, value: \"pineapple\" },\n ]\n\n const vegetables = [\n { label: t.carrot, value: \"carrot\" },\n { label: t.broccoli, value: \"broccoli\" },\n { label: t.spinach, value: \"spinach\" },\n ]\n\n const allItems = [\n { label: t.selectFruit, value: null },\n ...fruits,\n ...vegetables,\n ]\n\n return (\n \n \n \n \n \n \n {t.fruits}\n {fruits.map((item) => (\n \n {item.label}\n \n ))}\n \n \n \n {t.vegetables}\n {vegetables.map((item) => (\n \n {item.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/select/select-scrollable.tsx", + "content": "import {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nconst northAmerica = [\n { label: \"Eastern Standard Time\", value: \"est\" },\n { label: \"Central Standard Time\", value: \"cst\" },\n { label: \"Mountain Standard Time\", value: \"mst\" },\n { label: \"Pacific Standard Time\", value: \"pst\" },\n { label: \"Alaska Standard Time\", value: \"akst\" },\n { label: \"Hawaii Standard Time\", value: \"hst\" },\n]\n\nconst europeAfrica = [\n { label: \"Greenwich Mean Time\", value: \"gmt\" },\n { label: \"Central European Time\", value: \"cet\" },\n { label: \"Eastern European Time\", value: \"eet\" },\n { label: \"Western European Summer Time\", value: \"west\" },\n { label: \"Central Africa Time\", value: \"cat\" },\n { label: \"East Africa Time\", value: \"eat\" },\n]\n\nconst asia = [\n { label: \"Moscow Time\", value: \"msk\" },\n { label: \"India Standard Time\", value: \"ist\" },\n { label: \"China Standard Time\", value: \"cst_china\" },\n { label: \"Japan Standard Time\", value: \"jst\" },\n { label: \"Korea Standard Time\", value: \"kst\" },\n { label: \"Indonesia Central Standard Time\", value: \"ist_indonesia\" },\n]\n\nconst australiaPacific = [\n { label: \"Australian Western Standard Time\", value: \"awst\" },\n { label: \"Australian Central Standard Time\", value: \"acst\" },\n { label: \"Australian Eastern Standard Time\", value: \"aest\" },\n { label: \"New Zealand Standard Time\", value: \"nzst\" },\n { label: \"Fiji Time\", value: \"fjt\" },\n]\n\nconst southAmerica = [\n { label: \"Argentina Time\", value: \"art\" },\n { label: \"Bolivia Time\", value: \"bot\" },\n { label: \"Brasilia Time\", value: \"brt\" },\n { label: \"Chile Standard Time\", value: \"clt\" },\n]\n\nconst items = [\n { label: \"Select a timezone\", value: null },\n ...northAmerica,\n ...europeAfrica,\n ...asia,\n ...australiaPacific,\n ...southAmerica,\n]\n\nexport function SelectScrollable() {\n return (\n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/select/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/select.json b/public/r/react/styles/base-luma/select.json new file mode 100644 index 000000000..31e216080 --- /dev/null +++ b/public/r/react/styles/base-luma/select.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "select", + "title": "Select", + "description": "Displays a list of options for the user to pick from, triggered by a button.", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "files": [ + { + "path": "src/components/ui/select.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Select as SelectPrimitive } from \"@base-ui/react/select\"\nimport { cn } from \"cn\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\n\nconst Select = SelectPrimitive.Root\n\nfunction SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {\n return (\n \n )\n}\n\nfunction SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {\n return (\n \n )\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: SelectPrimitive.Trigger.Props & {\n size?: \"sm\" | \"default\"\n}) {\n return (\n \n {children}\n \n }\n />\n \n )\n}\n\nfunction SelectContent({\n className,\n children,\n side = \"bottom\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 0,\n alignItemWithTrigger = true,\n ...props\n}: SelectPrimitive.Popup.Props &\n Pick<\n SelectPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\" | \"alignItemWithTrigger\"\n >) {\n return (\n \n \n \n \n {children}\n \n \n \n \n )\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: SelectPrimitive.GroupLabel.Props) {\n return (\n \n )\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: SelectPrimitive.Item.Props) {\n return (\n \n \n {children}\n \n }\n >\n \n \n \n )\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: SelectPrimitive.Separator.Props) {\n return (\n \n )\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n \n \n )\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n \n \n )\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/select/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/separator-examples.json b/public/r/react/styles/base-luma/separator-examples.json new file mode 100644 index 000000000..5feadb15c --- /dev/null +++ b/public/r/react/styles/base-luma/separator-examples.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "separator-examples", + "title": "Separator examples", + "description": "The examples from the shadcn/ui Separator docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/select", + "@fulldev/separator" + ], + "files": [ + { + "path": "src/components/examples/separator/separator-demo.tsx", + "content": "import { Separator } from \"@/components/ui/separator\"\n\nexport function SeparatorDemo() {\n return (\n
    \n
    \n
    shadcn/ui
    \n
    \n The Foundation for your Design System\n
    \n
    \n \n
    \n A set of beautifully designed components that you can customize, extend,\n and build on.\n
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/separator/separator-list.tsx", + "content": "import { Separator } from \"@/components/ui/separator\"\n\nexport function SeparatorList() {\n return (\n
    \n
    \n
    Item 1
    \n
    Value 1
    \n
    \n \n
    \n
    Item 2
    \n
    Value 2
    \n
    \n \n
    \n
    Item 3
    \n
    Value 3
    \n
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/separator/separator-menu.tsx", + "content": "import { Separator } from \"@/components/ui/separator\"\n\nexport function SeparatorMenu() {\n return (\n
    \n
    \n Settings\n \n Manage preferences\n \n
    \n \n
    \n Account\n \n Profile & security\n \n
    \n \n
    \n Help\n Support & docs\n
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/separator/separator-rtl.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Separator } from \"@/components/ui/separator\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n title: \"shadcn/ui\",\n subtitle: \"The Foundation for your Design System\",\n description:\n \"A set of beautifully designed components that you can customize, extend, and build on.\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n title: \"shadcn/ui\",\n subtitle: \"الأساس لنظام التصميم الخاص بك\",\n description:\n \"مجموعة من المكونات المصممة بشكل جميل يمكنك تخصيصها وتوسيعها والبناء عليها.\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n title: \"shadcn/ui\",\n subtitle: \"הבסיס למערכת העיצוב שלך\",\n description:\n \"סט של רכיבים מעוצבים בצורה יפה שאתה יכול להתאים אישית, להרחיב ולבנות עליהם.\",\n },\n },\n}\n\nexport function SeparatorRtl() {\n const { dir, t } = useTranslation(translations, \"ar\")\n\n return (\n
    \n
    \n
    {t.title}
    \n
    {t.subtitle}
    \n
    \n \n
    {t.description}
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/separator/separator-vertical.tsx", + "content": "import { Separator } from \"@/components/ui/separator\"\n\nexport function SeparatorVertical() {\n return (\n
    \n
    Blog
    \n \n
    Docs
    \n \n
    Source
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/separator/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/separator.json b/public/r/react/styles/base-luma/separator.json new file mode 100644 index 000000000..2dee5e455 --- /dev/null +++ b/public/r/react/styles/base-luma/separator.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "separator", + "title": "Separator", + "description": "Visually or semantically separates content.", + "dependencies": [ + "@base-ui/react", + "cn" + ], + "files": [ + { + "path": "src/components/ui/separator.tsx", + "content": "\"use client\"\n\nimport { Separator as SeparatorPrimitive } from \"@base-ui/react/separator\"\nimport { cn } from \"cn\"\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n ...props\n}: SeparatorPrimitive.Props) {\n return (\n \n )\n}\n\nexport { Separator }\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/separator/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/services-1.json b/public/r/react/styles/base-luma/services-1.json new file mode 100644 index 000000000..9c7c11c3a --- /dev/null +++ b/public/r/react/styles/base-luma/services-1.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "services-1", + "title": "Services 1", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-1.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { placeholderImage } from \"@/lib/placeholder-image\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Services1({\n badge,\n title,\n buttons,\n services,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n buttons: {\n label: string\n href: string\n }[]\n services: {\n image?: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n label: string\n title: string\n description: string\n href?: string\n }[]\n}) {\n return (\n
    \n \n
    \n
    \n {badge}\n {title}\n
    \n
    \n {buttons.map(({ href, label }) => (\n \n {label}\n \n ))}\n
    \n
    \n
    \n {services.map((service) => {\n const image = service.image ?? { ...placeholderImage, alt: \"\" }\n const className = cn(\n \"group/service flex flex-col gap-4 overflow-hidden rounded-xl border shadow-xs\",\n service.href != null && \"transition-shadow hover:shadow-md\"\n )\n const content = (\n <>\n \n
    \n \n {service.label}\n \n

    {service.title}

    \n

    \n {service.description}\n

    \n {service.href != null && (\n \n \n \n )}\n
    \n \n )\n return service.href != null ? (\n \n {content}\n \n ) : (\n
    \n {content}\n
    \n )\n })}\n
    \n
    \n
    \n )\n}\n\nexport { Services1 }\n", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "content": "export const placeholderImage = {\n // The neutral image blocks show until a site passes its own.\n src: \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1536' height='864' viewBox='0 0 1536 864'%3E%3Cdefs%3E%3CradialGradient id='placeholder-background' cx='50%25' cy='50%25' r='70%25'%3E%3Cstop offset='0' stop-color='%23525252' /%3E%3Cstop offset='1' stop-color='%23404040' /%3E%3C/radialGradient%3E%3CradialGradient id='placeholder-fade' cx='50%25' cy='50%25' r='40%25'%3E%3Cstop offset='0' stop-color='%23ffffff' /%3E%3Cstop offset='1' stop-color='%23ffffff' stop-opacity='0' /%3E%3C/radialGradient%3E%3Cpattern id='placeholder-dots' width='20' height='20' patternUnits='userSpaceOnUse'%3E%3Ccircle cx='10' cy='10' r='2' fill='%23e5e5e5' /%3E%3C/pattern%3E%3Cmask id='placeholder-mask'%3E%3Crect width='1536' height='864' fill='url(%23placeholder-fade)' /%3E%3C/mask%3E%3C/defs%3E%3Crect width='1536' height='864' fill='url(%23placeholder-background)' /%3E%3Crect width='1536' height='864' fill='url(%23placeholder-dots)' mask='url(%23placeholder-mask)' /%3E%3C/svg%3E\",\n width: 1536,\n height: 864,\n}\n", + "type": "registry:lib" + } + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "categories": [ + "services" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/services-2.json b/public/r/react/styles/base-luma/services-2.json new file mode 100644 index 000000000..35c067768 --- /dev/null +++ b/public/r/react/styles/base-luma/services-2.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "services-2", + "title": "Services 2", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-2.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { placeholderImage } from \"@/lib/placeholder-image\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Services2({\n badge,\n title,\n description,\n services,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n description: string\n services: {\n image?: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n label: string\n title: string\n description: string\n button: {\n label: string\n href: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n {badge}\n {title}\n

    \n {description}\n

    \n
    \n
    \n {services.map((service) => {\n const image = service.image ?? { ...placeholderImage, alt: \"\" }\n return (\n \n \n
    \n \n {service.label}\n \n

    {service.title}

    \n

    \n {service.description}\n

    \n \n {service.button.label}\n \n
    \n
    \n )\n })}\n
    \n \n \n )\n}\n\nexport { Services2 }\n", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "content": "export const placeholderImage = {\n // The neutral image blocks show until a site passes its own.\n src: \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1536' height='864' viewBox='0 0 1536 864'%3E%3Cdefs%3E%3CradialGradient id='placeholder-background' cx='50%25' cy='50%25' r='70%25'%3E%3Cstop offset='0' stop-color='%23525252' /%3E%3Cstop offset='1' stop-color='%23404040' /%3E%3C/radialGradient%3E%3CradialGradient id='placeholder-fade' cx='50%25' cy='50%25' r='40%25'%3E%3Cstop offset='0' stop-color='%23ffffff' /%3E%3Cstop offset='1' stop-color='%23ffffff' stop-opacity='0' /%3E%3C/radialGradient%3E%3Cpattern id='placeholder-dots' width='20' height='20' patternUnits='userSpaceOnUse'%3E%3Ccircle cx='10' cy='10' r='2' fill='%23e5e5e5' /%3E%3C/pattern%3E%3Cmask id='placeholder-mask'%3E%3Crect width='1536' height='864' fill='url(%23placeholder-fade)' /%3E%3C/mask%3E%3C/defs%3E%3Crect width='1536' height='864' fill='url(%23placeholder-background)' /%3E%3Crect width='1536' height='864' fill='url(%23placeholder-dots)' mask='url(%23placeholder-mask)' /%3E%3C/svg%3E\",\n width: 1536,\n height: 864,\n}\n", + "type": "registry:lib" + } + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "categories": [ + "services" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/services-3.json b/public/r/react/styles/base-luma/services-3.json new file mode 100644 index 000000000..a00d1ac67 --- /dev/null +++ b/public/r/react/styles/base-luma/services-3.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "services-3", + "title": "Services 3", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-3.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport { placeholderImage } from \"@/lib/placeholder-image\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Services3({\n badge,\n title,\n description,\n buttons,\n services,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n services: {\n image?: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n title: string\n description: string\n button: {\n label: string\n href: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n {badge}\n {title}\n

    \n {description}\n

    \n
    \n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
    \n
    \n
    \n {services.map((service) => {\n const image = service.image ?? { ...placeholderImage, alt: \"\" }\n return (\n \n \n
    \n
    \n

    {service.title}

    \n

    \n {service.description}\n

    \n \n {service.button.label}\n \n
    \n
    \n )\n })}\n
    \n
    \n
    \n )\n}\n\nexport { Services3 }\n", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "content": "export const placeholderImage = {\n // The neutral image blocks show until a site passes its own.\n src: \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1536' height='864' viewBox='0 0 1536 864'%3E%3Cdefs%3E%3CradialGradient id='placeholder-background' cx='50%25' cy='50%25' r='70%25'%3E%3Cstop offset='0' stop-color='%23525252' /%3E%3Cstop offset='1' stop-color='%23404040' /%3E%3C/radialGradient%3E%3CradialGradient id='placeholder-fade' cx='50%25' cy='50%25' r='40%25'%3E%3Cstop offset='0' stop-color='%23ffffff' /%3E%3Cstop offset='1' stop-color='%23ffffff' stop-opacity='0' /%3E%3C/radialGradient%3E%3Cpattern id='placeholder-dots' width='20' height='20' patternUnits='userSpaceOnUse'%3E%3Ccircle cx='10' cy='10' r='2' fill='%23e5e5e5' /%3E%3C/pattern%3E%3Cmask id='placeholder-mask'%3E%3Crect width='1536' height='864' fill='url(%23placeholder-fade)' /%3E%3C/mask%3E%3C/defs%3E%3Crect width='1536' height='864' fill='url(%23placeholder-background)' /%3E%3Crect width='1536' height='864' fill='url(%23placeholder-dots)' mask='url(%23placeholder-mask)' /%3E%3C/svg%3E\",\n width: 1536,\n height: 864,\n}\n", + "type": "registry:lib" + } + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "categories": [ + "services" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/services-4.json b/public/r/react/styles/base-luma/services-4.json new file mode 100644 index 000000000..58cfade1e --- /dev/null +++ b/public/r/react/styles/base-luma/services-4.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "services-4", + "title": "Services 4", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-4.tsx", + "content": "import * as React from \"react\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { placeholderImage } from \"@/lib/placeholder-image\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Services4({\n title,\n description,\n buttons,\n services,\n ...props\n}: React.ComponentProps<\"section\"> & {\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n services: {\n image?: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n title: string\n description: string\n link?: {\n label: string\n href: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n
    \n {title}\n

    \n {description}\n

    \n
    \n
    \n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
    \n
    \n
    \n {services.map((service) => {\n const image = service.image ?? { ...placeholderImage, alt: \"\" }\n return (\n
    \n \n
    \n

    {service.title}

    \n

    \n {service.description}\n

    \n
    \n {service.link && (\n \n {service.link.label}\n \n \n )}\n
    \n )\n })}\n
    \n
    \n
    \n )\n}\n\nexport { Services4 }\n", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "content": "export const placeholderImage = {\n // The neutral image blocks show until a site passes its own.\n src: \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1536' height='864' viewBox='0 0 1536 864'%3E%3Cdefs%3E%3CradialGradient id='placeholder-background' cx='50%25' cy='50%25' r='70%25'%3E%3Cstop offset='0' stop-color='%23525252' /%3E%3Cstop offset='1' stop-color='%23404040' /%3E%3C/radialGradient%3E%3CradialGradient id='placeholder-fade' cx='50%25' cy='50%25' r='40%25'%3E%3Cstop offset='0' stop-color='%23ffffff' /%3E%3Cstop offset='1' stop-color='%23ffffff' stop-opacity='0' /%3E%3C/radialGradient%3E%3Cpattern id='placeholder-dots' width='20' height='20' patternUnits='userSpaceOnUse'%3E%3Ccircle cx='10' cy='10' r='2' fill='%23e5e5e5' /%3E%3C/pattern%3E%3Cmask id='placeholder-mask'%3E%3Crect width='1536' height='864' fill='url(%23placeholder-fade)' /%3E%3C/mask%3E%3C/defs%3E%3Crect width='1536' height='864' fill='url(%23placeholder-background)' /%3E%3Crect width='1536' height='864' fill='url(%23placeholder-dots)' mask='url(%23placeholder-mask)' /%3E%3C/svg%3E\",\n width: 1536,\n height: 864,\n}\n", + "type": "registry:lib" + } + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "categories": [ + "services" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/services-5.json b/public/r/react/styles/base-luma/services-5.json new file mode 100644 index 000000000..faebb5dd0 --- /dev/null +++ b/public/r/react/styles/base-luma/services-5.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "services-5", + "title": "Services 5", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/icon", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-5.tsx", + "content": "import * as React from \"react\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport { Icon } from \"@/components/ui/icon\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Services5({\n badge,\n title,\n description,\n services,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n description: string\n services: {\n icon: string\n title: string\n description: string\n link?: {\n label: string\n href: string\n }\n }[]\n}) {\n return (\n
    \n \n
    \n {badge}\n {title}\n

    \n {description}\n

    \n
    \n
    \n {services.map((service) => (\n \n
    \n \n
    \n

    \n {service.title}\n

    \n

    \n {service.description}\n

    \n {service.link && (\n \n {service.link.label}\n \n \n )}\n
    \n ))}\n \n
    \n
    \n )\n}\n\nexport { Services5 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "categories": [ + "services" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/services-6.json b/public/r/react/styles/base-luma/services-6.json new file mode 100644 index 000000000..276f1765e --- /dev/null +++ b/public/r/react/styles/base-luma/services-6.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "services-6", + "title": "Services 6", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-6.tsx", + "content": "import * as React from \"react\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { placeholderImage } from \"@/lib/placeholder-image\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\nfunction Services6({\n badge,\n title,\n description,\n buttons,\n services,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n description: string\n buttons: {\n label: string\n href: string\n }[]\n services: {\n image?: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n title: string\n description: string\n href?: string\n }[]\n}) {\n return (\n
    \n \n
    \n {badge}\n

    \n {title}\n

    \n

    \n {description}\n

    \n
    \n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
    \n
    \n
    \n {services.map((service) => {\n const image = service.image ?? { ...placeholderImage, alt: \"\" }\n return (\n \n \n
    \n
    \n
    \n

    {service.title}

    \n

    \n {service.description}\n

    \n
    \n {service.href != null && (\n \n \n \n )}\n
    \n
    \n )\n })}\n
    \n
    \n
    \n )\n}\n\nexport { Services6 }\n", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "content": "export const placeholderImage = {\n // The neutral image blocks show until a site passes its own.\n src: \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1536' height='864' viewBox='0 0 1536 864'%3E%3Cdefs%3E%3CradialGradient id='placeholder-background' cx='50%25' cy='50%25' r='70%25'%3E%3Cstop offset='0' stop-color='%23525252' /%3E%3Cstop offset='1' stop-color='%23404040' /%3E%3C/radialGradient%3E%3CradialGradient id='placeholder-fade' cx='50%25' cy='50%25' r='40%25'%3E%3Cstop offset='0' stop-color='%23ffffff' /%3E%3Cstop offset='1' stop-color='%23ffffff' stop-opacity='0' /%3E%3C/radialGradient%3E%3Cpattern id='placeholder-dots' width='20' height='20' patternUnits='userSpaceOnUse'%3E%3Ccircle cx='10' cy='10' r='2' fill='%23e5e5e5' /%3E%3C/pattern%3E%3Cmask id='placeholder-mask'%3E%3Crect width='1536' height='864' fill='url(%23placeholder-fade)' /%3E%3C/mask%3E%3C/defs%3E%3Crect width='1536' height='864' fill='url(%23placeholder-background)' /%3E%3Crect width='1536' height='864' fill='url(%23placeholder-dots)' mask='url(%23placeholder-mask)' /%3E%3C/svg%3E\",\n width: 1536,\n height: 864,\n}\n", + "type": "registry:lib" + } + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "categories": [ + "services" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/services-7.json b/public/r/react/styles/base-luma/services-7.json new file mode 100644 index 000000000..8f506a371 --- /dev/null +++ b/public/r/react/styles/base-luma/services-7.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "services-7", + "title": "Services 7", + "description": "Service section layouts for agencies, consultancies, and internal platform teams.", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/badge", + "@fulldev/button", + "@fulldev/section" + ], + "files": [ + { + "path": "src/components/blocks/services-7.tsx", + "content": "import * as React from \"react\"\nimport { cn } from \"cn\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { placeholderImage } from \"@/lib/placeholder-image\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { buttonVariants } from \"@/components/ui/button\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\nfunction Services7({\n badge,\n title,\n description,\n buttons,\n linkLabel,\n services,\n ...props\n}: React.ComponentProps<\"section\"> & {\n badge: string\n title: string\n description: string\n linkLabel: string\n buttons: {\n label: string\n href: string\n }[]\n services: {\n image?: {\n src: string\n srcSet?: string\n alt: string\n width?: number\n height?: number\n }\n label: string\n title: string\n description: string\n href?: string\n }[]\n}) {\n return (\n
    \n \n
    \n
    \n {badge}\n {title}\n

    \n {description}\n

    \n
    \n
    \n {buttons.map(({ href, label }, index) => (\n \n {label}\n \n ))}\n
    \n
    \n
    \n {services.map((service, index) => {\n const image = service.image ?? { ...placeholderImage, alt: \"\" }\n const className = cn(\n \"group/service flex flex-col overflow-hidden rounded-xl border shadow-xs\",\n service.href != null && \"transition-shadow hover:shadow-md\",\n index === 0 && \"lg:col-span-2 lg:row-span-2\"\n )\n const content = (\n <>\n \n
    \n \n {service.label}\n \n \n {service.title}\n \n

    \n {service.description}\n

    \n {service.href != null && (\n \n {linkLabel}\n \n
    \n )}\n
    \n \n )\n return service.href != null ? (\n \n {content}\n \n ) : (\n
    \n {content}\n
    \n )\n })}\n \n
    \n
    \n )\n}\n\nexport { Services7 }\n", + "type": "registry:block" + }, + { + "path": "src/lib/placeholder-image.ts", + "content": "export const placeholderImage = {\n // The neutral image blocks show until a site passes its own.\n src: \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1536' height='864' viewBox='0 0 1536 864'%3E%3Cdefs%3E%3CradialGradient id='placeholder-background' cx='50%25' cy='50%25' r='70%25'%3E%3Cstop offset='0' stop-color='%23525252' /%3E%3Cstop offset='1' stop-color='%23404040' /%3E%3C/radialGradient%3E%3CradialGradient id='placeholder-fade' cx='50%25' cy='50%25' r='40%25'%3E%3Cstop offset='0' stop-color='%23ffffff' /%3E%3Cstop offset='1' stop-color='%23ffffff' stop-opacity='0' /%3E%3C/radialGradient%3E%3Cpattern id='placeholder-dots' width='20' height='20' patternUnits='userSpaceOnUse'%3E%3Ccircle cx='10' cy='10' r='2' fill='%23e5e5e5' /%3E%3C/pattern%3E%3Cmask id='placeholder-mask'%3E%3Crect width='1536' height='864' fill='url(%23placeholder-fade)' /%3E%3C/mask%3E%3C/defs%3E%3Crect width='1536' height='864' fill='url(%23placeholder-background)' /%3E%3Crect width='1536' height='864' fill='url(%23placeholder-dots)' mask='url(%23placeholder-mask)' /%3E%3C/svg%3E\",\n width: 1536,\n height: 864,\n}\n", + "type": "registry:lib" + } + ], + "docs": "https://ui.full.dev/react/blocks/services/", + "categories": [ + "services" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/sheet-examples.json b/public/r/react/styles/base-luma/sheet-examples.json new file mode 100644 index 000000000..c1aec6016 --- /dev/null +++ b/public/r/react/styles/base-luma/sheet-examples.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "sheet-examples", + "title": "Sheet examples", + "description": "The examples from the shadcn/ui Sheet docs.", + "dependencies": [ + "cn" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/field", + "@fulldev/input", + "@fulldev/label", + "@fulldev/select", + "@fulldev/sheet" + ], + "files": [ + { + "path": "src/components/examples/sheet/sheet-demo.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport { Label } from \"@/components/ui/label\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\"\n\nexport function SheetDemo() {\n return (\n \n }>Open\n \n \n Edit profile\n \n Make changes to your profile here. Click save when you're done.\n \n \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n \n \n }>Close\n \n
    \n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/sheet/sheet-no-close-button.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\"\n\nexport function SheetNoCloseButton() {\n return (\n \n }>\n Open Sheet\n \n \n \n No Close Button\n \n This sheet doesn't have a close button in the top-right corner.\n Click outside to close.\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/sheet/sheet-rtl.tsx", + "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\"\nimport {\n useTranslation,\n type Translations,\n} from \"@/components/language-selector\"\n\nconst translations: Translations = {\n en: {\n dir: \"ltr\",\n values: {\n open: \"Open\",\n editProfile: \"Edit profile\",\n description:\n \"Make changes to your profile here. Click save when you're done.\",\n name: \"Name\",\n username: \"Username\",\n save: \"Save changes\",\n close: \"Close\",\n },\n },\n ar: {\n dir: \"rtl\",\n values: {\n open: \"فتح\",\n editProfile: \"تعديل الملف الشخصي\",\n description:\n \"قم بإجراء تغييرات على ملفك الشخصي هنا. انقر حفظ عند الانتهاء.\",\n name: \"الاسم\",\n username: \"اسم المستخدم\",\n save: \"حفظ التغييرات\",\n close: \"إغلاق\",\n },\n },\n he: {\n dir: \"rtl\",\n values: {\n open: \"פתח\",\n editProfile: \"עריכת פרופיל\",\n description: \"בצע שינויים בפרופיל שלך כאן. לחץ שמור כשתסיים.\",\n name: \"שם\",\n username: \"שם משתמש\",\n save: \"שמור שינויים\",\n close: \"סגור\",\n },\n },\n}\n\nexport function SheetRtl() {\n const { dir, t, language } = useTranslation(translations, \"ar\")\n\n return (\n \n }>\n {t.open}\n \n \n \n {t.editProfile}\n {t.description}\n \n \n \n {t.name}\n \n \n \n {t.username}\n \n \n \n \n \n }>\n {t.close}\n \n \n \n \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/examples/sheet/sheet-side.tsx", + "content": "import { Button } from \"@/components/ui/button\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\"\n\nconst SHEET_SIDES = [\"top\", \"right\", \"bottom\", \"left\"] as const\n\nexport function SheetSide() {\n return (\n
    \n {SHEET_SIDES.map((side) => (\n \n }\n >\n {side}\n \n \n \n Edit profile\n \n Make changes to your profile here. Click save when you're\n done.\n \n \n
    \n {Array.from({ length: 10 }).map((_, index) => (\n

    \n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed\n do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n Ut enim ad minim veniam, quis nostrud exercitation ullamco\n laboris nisi ut aliquip ex ea commodo consequat. Duis aute\n irure dolor in reprehenderit in voluptate velit esse cillum\n dolore eu fugiat nulla pariatur. Excepteur sint occaecat\n cupidatat non proident, sunt in culpa qui officia deserunt\n mollit anim id est laborum.\n

    \n ))}\n
    \n \n \n }>\n Cancel\n \n \n \n
    \n ))}\n
    \n )\n}\n", + "type": "registry:component" + }, + { + "path": "src/components/language-selector.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\"\n\nexport type Language = \"en\" | \"ar\" | \"he\"\n\nexport type Direction = \"ltr\" | \"rtl\"\n\nexport type Translations<\n T extends Record = Record,\n> = Record<\n Language,\n {\n dir: Direction\n locale?: string\n values: T\n }\n>\n\nexport const languageOptions = [\n { value: \"en\", label: \"English\" },\n { value: \"ar\", label: \"Arabic (العربية)\" },\n { value: \"he\", label: \"Hebrew (עברית)\" },\n] as const\n\ntype LanguageContextType = {\n language: Language\n setLanguage: (language: Language) => void\n}\n\nconst LanguageContext = React.createContext(\n undefined\n)\n\nexport function LanguageProvider({\n children,\n defaultLanguage = \"ar\",\n}: {\n children: React.ReactNode\n defaultLanguage?: Language\n}) {\n const [language, setLanguage] = React.useState(defaultLanguage)\n\n return (\n \n {children}\n \n )\n}\n\nexport function useLanguageContext() {\n const context = React.useContext(LanguageContext)\n return context\n}\n\nexport function useTranslation>(\n translations: Translations,\n defaultLanguage: Language = \"ar\"\n) {\n const context = useLanguageContext()\n const [localLanguage, setLocalLanguage] =\n React.useState(defaultLanguage)\n\n const language = context?.language ?? localLanguage\n const setLanguage = context?.setLanguage ?? setLocalLanguage\n\n const { dir, locale, values: t } = translations[language]\n return { language, setLanguage, dir, locale, t }\n}\n\nexport interface LanguageSelectorProps {\n value: Language\n onValueChange: (value: Language) => void\n}\n\nexport function LanguageSelector({\n value,\n onValueChange,\n className,\n languages = [\"en\", \"ar\", \"he\"],\n}: LanguageSelectorProps & {\n className?: string\n languages?: Language[]\n}) {\n return (\n onValueChange(value as Language)}\n >\n \n \n \n \n \n {languageOptions\n .filter((option) => languages.includes(option.value as Language))\n .map((option) => (\n \n {option.label}\n \n ))}\n \n \n \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/sheet/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/sheet.json b/public/r/react/styles/base-luma/sheet.json new file mode 100644 index 000000000..08d356290 --- /dev/null +++ b/public/r/react/styles/base-luma/sheet.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "sheet", + "title": "Sheet", + "description": "A sliding panel component that appears from the edge of the screen.", + "dependencies": [ + "@base-ui/react", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button" + ], + "files": [ + { + "path": "src/components/ui/sheet.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Dialog as SheetPrimitive } from \"@base-ui/react/dialog\"\nimport { cn } from \"cn\"\nimport { XIcon } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nfunction Sheet({ ...props }: SheetPrimitive.Root.Props) {\n return \n}\n\nfunction SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {\n return \n}\n\nfunction SheetClose({ ...props }: SheetPrimitive.Close.Props) {\n return \n}\n\nfunction SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {\n return \n}\n\nfunction SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {\n return (\n \n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n showCloseButton = true,\n ...props\n}: SheetPrimitive.Popup.Props & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n showCloseButton?: boolean\n}) {\n return (\n \n \n \n {children}\n {showCloseButton && (\n \n }\n >\n \n Close\n \n )}\n \n \n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {\n return (\n \n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: SheetPrimitive.Description.Props) {\n return (\n \n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n", + "type": "registry:ui" + } + ], + "docs": "https://ui.full.dev/react/components/sheet/", + "categories": [ + "ui" + ], + "type": "registry:ui" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/sidebar-1.json b/public/r/react/styles/base-luma/sidebar-1.json new file mode 100644 index 000000000..67f56a382 --- /dev/null +++ b/public/r/react/styles/base-luma/sidebar-1.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "sidebar-1", + "title": "Sidebar 1", + "dependencies": [ + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/breadcrumb", + "@fulldev/button", + "@fulldev/command", + "@fulldev/dropdown-menu", + "@fulldev/header", + "@fulldev/icon", + "@fulldev/kbd", + "@fulldev/logo", + "@fulldev/separator", + "@fulldev/sidebar", + "@fulldev/theme-toggle" + ], + "files": [ + { + "path": "src/components/blocks/sidebar-1.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\nimport { ChevronDownIcon, SearchIcon } from \"lucide-react\"\n\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\nimport { Button, buttonVariants } 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 {\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\nconst normalizePath = (path: string) =>\n path === \"/\" ? path : path.replace(/\\/$/, \"\")\n\nconst subscribe = () => () => {}\n\n// The server renders the Mac shortcut; the browser shows its own.\nfunction useIsMac() {\n return React.useSyncExternalStore(\n subscribe,\n () =>\n /Mac|iPhone|iPad|iPod/i.test(navigator.platform || navigator.userAgent),\n () => true\n )\n}\n\nfunction Sidebar1({\n currentPath: rawCurrentPath,\n logo,\n search,\n breadcrumb,\n navigation,\n githubRepo,\n githubStars,\n labels,\n header,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n currentPath: string\n header?: React.ReactNode\n logo: {\n label: string\n href: string\n src?: string\n srcLight?: string\n srcDark?: 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 githubStars?: number\n labels: {\n sidebar: string\n github: string\n stars: string\n breadcrumb: string\n breadcrumbMenu: string\n sidebarToggle: string\n mobileTitle: string\n mobileDescription: string\n theme: string\n shortcut: {\n mac: string\n other: string\n }\n }\n}) {\n const currentPath = normalizePath(rawCurrentPath)\n const isMac = useIsMac()\n const [searchOpen, setSearchOpen] = React.useState(false)\n\n // Command or Control + K opens the search from anywhere on the page.\n React.useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key.toLowerCase() !== \"k\") return\n if (event.shiftKey || event.altKey) return\n const shortcut = isMac\n ? event.metaKey && !event.ctrlKey\n : event.ctrlKey && !event.metaKey\n if (!shortcut) return\n event.preventDefault()\n setSearchOpen(true)\n }\n document.addEventListener(\"keydown\", onKeyDown)\n return () => document.removeEventListener(\"keydown\", onKeyDown)\n }, [isMac])\n\n const 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 if (group) group.items.push(item)\n else groups.push({ label: item.group, items: [item] })\n return groups\n }, [])\n\n const githubStarsLabel =\n githubStars === undefined\n ? labels.stars\n : new Intl.NumberFormat().format(githubStars)\n\n return (\n \n {/* Outside the sidebar, which unmounts on mobile while closed, so the\n shortcut opens the search at any time. */}\n \n \n \n \n {search.empty}\n {searchGroups.map((group) => (\n \n {group.items.map((item) => (\n window.location.assign(item.href)}\n >\n {item.label}\n {item.href}\n \n ))}\n \n ))}\n \n \n \n \n \n }>\n \n {logo.label}\n \n {header}\n setSearchOpen(true)}\n >\n \n {search.label}\n \n {isMac ? labels.shortcut.mac : labels.shortcut.other}\n \n \n \n \n {navigation.map((group) => (\n \n {group.label}\n \n {(group.links ?? [group]).map((item) => (\n \n }\n isActive={normalizePath(item.href) === currentPath}\n >\n {item.label}\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 hasMenu =\n item.href !== \"/\" &&\n breadcrumb.menu.some(\n (menuItem) =>\n normalizePath(menuItem.href) ===\n normalizePath(item.href)\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 }\n className=\"aria-[current=page]:text-foreground\"\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 {breadcrumb.menu.length > 0 && currentPath === \"/\" && (\n <>\n /\n \n \n \n \n \n {labels.breadcrumbMenu}\n \n \n \n \n {breadcrumb.menu.map((item) => (\n }\n >\n {item.label}\n \n ))}\n \n \n \n \n \n )}\n \n \n \n \n \n \n {labels.github}\n {githubStarsLabel}\n \n \n \n \n
    \n {children}\n
    \n
    \n )\n}\n\nexport { Sidebar1 }\n", + "type": "registry:block" + } + ], + "docs": "https://ui.full.dev/react/blocks/sidebar/", + "categories": [ + "sidebar" + ], + "type": "registry:block" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/sidebar-examples.json b/public/r/react/styles/base-luma/sidebar-examples.json new file mode 100644 index 000000000..9598358f5 --- /dev/null +++ b/public/r/react/styles/base-luma/sidebar-examples.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "sidebar-examples", + "title": "Sidebar examples", + "description": "The examples from the shadcn/ui Sidebar docs.", + "dependencies": [ + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/avatar", + "@fulldev/collapsible", + "@fulldev/dropdown-menu", + "@fulldev/sidebar" + ], + "files": [ + { + "path": "src/components/examples/sidebar/sidebar-demo.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n AudioWaveform,\n BadgeCheck,\n Bell,\n BookOpen,\n Bot,\n ChevronRight,\n ChevronsUpDown,\n Command,\n CreditCard,\n Folder,\n Forward,\n Frame,\n GalleryVerticalEnd,\n LogOut,\n Map,\n MoreHorizontal,\n PieChart,\n Plus,\n Settings2,\n Sparkles,\n SquareTerminal,\n Trash2,\n} from \"lucide-react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarTrigger,\n useSidebar,\n} from \"@/components/ui/sidebar\"\n\n// This is sample data.\nconst data = {\n user: {\n name: \"shadcn\",\n email: \"m@example.com\",\n avatar: \"https://ui.shadcn.com/avatars/shadcn.jpg\",\n },\n teams: [\n {\n name: \"Acme Inc\",\n logo: GalleryVerticalEnd,\n plan: \"Enterprise\",\n },\n {\n name: \"Acme Corp.\",\n logo: AudioWaveform,\n plan: \"Startup\",\n },\n {\n name: \"Evil Corp.\",\n logo: Command,\n plan: \"Free\",\n },\n ],\n navMain: [\n {\n title: \"Playground\",\n url: \"#\",\n icon: SquareTerminal,\n isActive: true,\n items: [\n {\n title: \"History\",\n url: \"#\",\n },\n {\n title: \"Starred\",\n url: \"#\",\n },\n {\n title: \"Settings\",\n url: \"#\",\n },\n ],\n },\n {\n title: \"Models\",\n url: \"#\",\n icon: Bot,\n items: [\n {\n title: \"Genesis\",\n url: \"#\",\n },\n {\n title: \"Explorer\",\n url: \"#\",\n },\n {\n title: \"Quantum\",\n url: \"#\",\n },\n ],\n },\n {\n title: \"Documentation\",\n url: \"#\",\n icon: BookOpen,\n items: [\n {\n title: \"Introduction\",\n url: \"#\",\n },\n {\n title: \"Get Started\",\n url: \"#\",\n },\n {\n title: \"Tutorials\",\n url: \"#\",\n },\n {\n title: \"Changelog\",\n url: \"#\",\n },\n ],\n },\n {\n title: \"Settings\",\n url: \"#\",\n icon: Settings2,\n items: [\n {\n title: \"General\",\n url: \"#\",\n },\n {\n title: \"Team\",\n url: \"#\",\n },\n {\n title: \"Billing\",\n url: \"#\",\n },\n {\n title: \"Limits\",\n url: \"#\",\n },\n ],\n },\n ],\n projects: [\n {\n name: \"Design Engineering\",\n url: \"#\",\n icon: Frame,\n },\n {\n name: \"Sales & Marketing\",\n url: \"#\",\n icon: PieChart,\n },\n {\n name: \"Travel\",\n url: \"#\",\n icon: Map,\n },\n ],\n}\n\nfunction TeamSwitcher({\n teams,\n}: {\n teams: {\n name: string\n logo: React.ElementType\n plan: string\n }[]\n}) {\n const { isMobile } = useSidebar()\n const [activeTeam, setActiveTeam] = React.useState(teams[0])\n\n if (!activeTeam) {\n return null\n }\n\n return (\n \n \n \n \n }\n >\n
    \n \n
    \n
    \n {activeTeam.name}\n {activeTeam.plan}\n
    \n \n \n \n \n \n Teams\n \n {teams.map((team, index) => (\n setActiveTeam(team)}\n className=\"gap-2 p-2\"\n >\n
    \n \n
    \n {team.name}\n ⌘{index + 1}\n \n ))}\n
    \n \n \n \n
    \n \n
    \n
    \n Add team\n
    \n
    \n
    \n \n
    \n
    \n
    \n )\n}\n\nfunction NavMain({\n items,\n}: {\n items: {\n title: string\n url: string\n icon?: React.ElementType\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }[]\n}) {\n return (\n \n Platform\n \n {items.map((item) => (\n \n \n }\n >\n {item.icon && }\n {item.title}\n \n \n \n \n {item.items?.map((subItem) => (\n \n }>\n {subItem.title}\n \n \n ))}\n \n \n \n \n ))}\n \n \n )\n}\n\nfunction NavProjects({\n projects,\n}: {\n projects: {\n name: string\n url: string\n icon: React.ElementType\n }[]\n}) {\n const { isMobile } = useSidebar()\n\n return (\n \n Projects\n \n {projects.map((item) => (\n \n }>\n \n {item.name}\n \n \n }>\n \n More\n \n \n \n \n View Project\n \n \n \n Share Project\n \n \n \n \n Delete Project\n \n \n \n \n ))}\n \n \n \n More\n \n \n \n \n )\n}\n\nfunction NavUser({\n user,\n}: {\n user: {\n name: string\n email: string\n avatar: string\n }\n}) {\n const { isMobile } = useSidebar()\n\n return (\n \n \n \n \n }\n >\n \n \n CN\n \n
    \n {user.name}\n {user.email}\n
    \n \n \n \n \n \n
    \n \n \n CN\n \n
    \n {user.name}\n {user.email}\n
    \n
    \n
    \n
    \n \n \n \n \n Upgrade to Pro\n \n \n \n \n \n \n Account\n \n \n \n Billing\n \n \n \n Notifications\n \n \n \n \n \n \n Log out\n \n \n \n
    \n
    \n
    \n )\n}\n\nexport function AppSidebar({ ...props }: React.ComponentProps) {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    \n
    \n \n
    \n
    \n
    \n
    \n )\n}\n", + "type": "registry:component" + } + ], + "docs": "https://ui.full.dev/react/components/sidebar/", + "type": "registry:example" +} \ No newline at end of file diff --git a/public/r/react/styles/base-luma/sidebar.json b/public/r/react/styles/base-luma/sidebar.json new file mode 100644 index 000000000..0e199e72e --- /dev/null +++ b/public/r/react/styles/base-luma/sidebar.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "sidebar", + "title": "Sidebar", + "description": "A composable, themeable and customizable sidebar component.", + "dependencies": [ + "@base-ui/react", + "class-variance-authority", + "cn", + "lucide-react" + ], + "registryDependencies": [ + "@fulldev/button", + "@fulldev/input", + "@fulldev/separator", + "@fulldev/sheet", + "@fulldev/skeleton", + "@fulldev/tooltip", + "@fulldev/use-mobile" + ], + "files": [ + { + "path": "src/components/ui/sidebar.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\nimport { PanelLeftIcon } from \"lucide-react\"\n\nimport { useIsMobile } from \"@/hooks/use-mobile\"\nimport { Button } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport { Separator } from \"@/components/ui/separator\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"@/components/ui/sheet\"\nimport { Skeleton } from \"@/components/ui/skeleton\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n}\n\nconst SidebarContext = React.createContext(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n}) {\n const isMobile = useIsMobile()\n const [openMobile, setOpenMobile] = React.useState(false)\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n },\n [setOpenProp, open]\n )\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n // Adds a keyboard shortcut to toggle the sidebar.\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault()\n toggleSidebar()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [toggleSidebar])\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\n )\n\n return (\n \n \n {children}\n \n \n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n dir,\n mobileTitle = \"Sidebar\",\n mobileDescription = \"Displays the mobile sidebar.\",\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n // The accessible name and description of the mobile sheet, in the page language.\n mobileTitle?: string\n mobileDescription?: string\n}) {\n const { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n \n {children}\n \n )\n }\n\n if (isMobile) {\n return (\n \n button]:hidden\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n \n {mobileTitle}\n {mobileDescription}\n \n
    {children}
    \n \n
    \n )\n }\n\n return (\n