tembro 4.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/components/charts/charts.d.ts +16 -5
- package/dist/src/components/charts/charts.cjs +1 -1
- package/dist/src/components/charts/charts.js +343 -252
- package/dist/src/components/layout/workspace-layout.cjs +1 -1
- package/dist/src/components/layout/workspace-layout.js +3 -3
- package/package.json +1 -1
- package/packages/cli/dist/index.cjs +1 -1
- package/packages/cli/vendor/src/components/charts/charts.tsx +55 -15
- package/packages/cli/vendor/src/components/layout/workspace-layout.tsx +3 -3
- package/packages/cli/vendor/templates/showcase/src/showcase/layout/HeroSection.tsx +2 -2
- package/packages/cli/vendor/templates/showcase/src/showcase/layout/WorkbenchSidebar.tsx +1 -1
- package/packages/cli/vendor/templates/styles/globals.css +45 -23
- package/registry.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/utils.cjs");let n=require("react");n=e.__toESM(n,1);let r=require("react/jsx-runtime");function i({viewport:e=!0,className:n,...i}){return(0,r.jsx)(`div`,{"data-slot":`workspace-layout`,"data-viewport":e||void 0,className:t.cn(`flex min-h-0 min-w-0 bg-[color:var(--aui-page-bg,var(--background))] text-foreground`,e&&`h-dvh overflow-hidden`,n),...i})}function a({className:e,...n}){return(0,r.jsx)(`div`,{"data-slot":`workspace-content`,className:t.cn(`flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden`,e),...n})}function o({scrollable:e=!0,padded:n=!1,className:i,...a}){return(0,r.jsx)(`main`,{"data-slot":`workspace-main`,"data-scrollable":e||void 0,className:t.cn(`min-h-0 min-w-0 flex-1`,e&&`overflow-x-hidden overflow-y-auto overscroll-contain`,n&&`p-4 md:p-6`,i),...a})}exports.WorkspaceContent=a,exports.WorkspaceLayout=i,exports.WorkspaceMain=o;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/utils.cjs");let n=require("react");n=e.__toESM(n,1);let r=require("react/jsx-runtime");function i({viewport:e=!0,className:n,...i}){return(0,r.jsx)(`div`,{"data-slot":`workspace-layout`,"data-viewport":e||void 0,className:t.cn(`flex min-h-0 min-w-0 bg-[color:var(--aui-page-bg,var(--background))] text-foreground`,e&&`h-dvh max-h-dvh w-full overflow-hidden overscroll-none`,n),...i})}function a({className:e,...n}){return(0,r.jsx)(`div`,{"data-slot":`workspace-content`,className:t.cn(`isolate flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden`,e),...n})}function o({scrollable:e=!0,padded:n=!1,className:i,...a}){return(0,r.jsx)(`main`,{"data-slot":`workspace-main`,"data-scrollable":e||void 0,className:t.cn(`min-h-0 min-w-0 flex-1`,e&&`overflow-x-hidden overflow-y-auto overscroll-contain [scrollbar-gutter:stable]`,n&&`p-4 md:p-6`,i),...a})}exports.WorkspaceContent=a,exports.WorkspaceLayout=i,exports.WorkspaceMain=o;
|
|
@@ -6,14 +6,14 @@ function n({ viewport: n = !0, className: r, ...i }) {
|
|
|
6
6
|
return /* @__PURE__ */ t("div", {
|
|
7
7
|
"data-slot": "workspace-layout",
|
|
8
8
|
"data-viewport": n || void 0,
|
|
9
|
-
className: e("flex min-h-0 min-w-0 bg-[color:var(--aui-page-bg,var(--background))] text-foreground", n && "h-dvh overflow-hidden", r),
|
|
9
|
+
className: e("flex min-h-0 min-w-0 bg-[color:var(--aui-page-bg,var(--background))] text-foreground", n && "h-dvh max-h-dvh w-full overflow-hidden overscroll-none", r),
|
|
10
10
|
...i
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
function r({ className: n, ...r }) {
|
|
14
14
|
return /* @__PURE__ */ t("div", {
|
|
15
15
|
"data-slot": "workspace-content",
|
|
16
|
-
className: e("flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", n),
|
|
16
|
+
className: e("isolate flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", n),
|
|
17
17
|
...r
|
|
18
18
|
});
|
|
19
19
|
}
|
|
@@ -21,7 +21,7 @@ function i({ scrollable: n = !0, padded: r = !1, className: i, ...a }) {
|
|
|
21
21
|
return /* @__PURE__ */ t("main", {
|
|
22
22
|
"data-slot": "workspace-main",
|
|
23
23
|
"data-scrollable": n || void 0,
|
|
24
|
-
className: e("min-h-0 min-w-0 flex-1", n && "overflow-x-hidden overflow-y-auto overscroll-contain", r && "p-4 md:p-6", i),
|
|
24
|
+
className: e("min-h-0 min-w-0 flex-1", n && "overflow-x-hidden overflow-y-auto overscroll-contain [scrollbar-gutter:stable]", r && "p-4 md:p-6", i),
|
|
25
25
|
...a
|
|
26
26
|
});
|
|
27
27
|
}
|
package/package.json
CHANGED
|
@@ -2002,4 +2002,4 @@ ${t}`),i.forEach(o=>{let n=R[o],s=nr(o),a=jo(o,n.category),c=n.registryDependenc
|
|
|
2002
2002
|
${s}`),a.sort().forEach(c=>{let d=R[c],l=nr(c),u=jo(c,d.category),h=d.registryDependencies?.length?` -> ${d.registryDependencies.join(", ")}`:"";console.log(` ${c} [${l}/${u}]${h}`);});console.log(`
|
|
2003
2003
|
Status:`),console.log(" stable = safe public API"),console.log(" preview = usable but API may change"),console.log(" experimental = not ready for stable app contracts"),console.log(" internal = helper metadata"),console.log(`
|
|
2004
2004
|
Distribution:`),console.log(" foundation = small runtime-safe primitives, hooks, and helpers"),console.log(" source-copy = copy into app source with init/add and edit locally"),console.log(" system = larger product surfaces and patterns; prefer source-copy only"),console.log(`
|
|
2005
|
-
Usage:`),console.log(` ${re("add button input data-table")}`),console.log(` ${re("add form --overwrite")}`),console.log(` ${re("list --category data-table")}`),console.log(` ${re("list --json")}`);}var mt=be(qe());function Ja(t){try{return mt.default.readJsonSync(t)}catch{return null}}function nw(t){try{return mt.default.readFileSync(t,"utf8")}catch{return null}}function FP(t,e){return e?L__default.default.resolve(t,e):null}function sw(t){let e=t.paths?.components??t.componentsPath??"src/components",r=t.paths?.ui??t.componentsPath??L__default.default.join(e,"ui"),i=t.paths?.lib??L__default.default.dirname(t.utilsPath??"src/lib/utils.ts"),o=t.paths?.hooks??"src/hooks",n=t.utilsPath??L__default.default.join(i,"utils.ts");return {componentsRoot:e,uiPath:r,libPath:i,hooksPath:o,utilsPath:n}}function jP(t,e){let r=sw(e);return t.replace("{components}",r.componentsRoot).replace("{ui}",r.uiPath).replace("{hooks}",r.hooksPath).replace("{lib}",r.libPath).replace("{utils}",r.utilsPath)}function iw(t,e){return ["tsconfig.app.json","tsconfig.json"].map(i=>L__default.default.join(t,i)).some(i=>!!Ja(i)?.compilerOptions?.paths?.[`${e}/*`])}function ow(t,e){return ["vite.config.ts","vite.config.js","vite.config.mjs"].map(i=>L__default.default.join(t,i)).some(i=>{let o=nw(i);return !!(o?.includes(`"${e}"`)||o?.includes(`'${e}'`))})}function aw(t,e){let r=Ja(L__default.default.join(t,"package.json")),i=new Set([...Object.keys(r?.dependencies??{}),...Object.keys(r?.devDependencies??{})]);return e.filter(o=>!i.has(o))}function Ya(t,e){return (t.files??[]).map(r=>({source:r.source,target:jP(r.target,e)}))}function NP(t,e){return At.map(r=>R[r]).filter(r=>r.category!=="lib").filter(r=>!r.migrationAliasFor).filter(r=>r.files?.length).filter(r=>Ya(r,e).some(i=>mt.default.existsSync(L__default.default.join(t,i.target))))}function qP(t,e){let r=NP(t,e),i=[],o=[],n=new Set;for(let s of r){for(let a of Ya(s,e))mt.default.existsSync(L__default.default.join(t,a.target))||i.push(`${s.name}: ${a.target}`);for(let a of s.registryDependencies??[]){let c=R[a];if(!c?.files?.length)continue;Ya(c,e).some(l=>mt.default.existsSync(L__default.default.join(t,l.target)))||o.push(`${s.name} -> ${a}`);}for(let a of s.dependencies??[])n.add(a);}return {copiedItems:r,missingFiles:i,missingRegistryDependencies:o,missingPackages:aw(t,Array.from(n).sort())}}function Ze(t,e){t.push(e);}function LP(t){return t?t.includes("/* tembro:start */")||t.includes("--aui-")||t.includes("--az-"):false}function cw(t={}){let e=process.cwd(),r=[],i=L__default.default.join(e,"package.json"),o=L__default.default.join(e,"tembro.json"),n=mt.default.existsSync(i),s=Ja(o);if(Ze(r,{name:"package.json",status:n?"pass":"fail",message:n?"package.json topildi.":"package.json topilmadi. Commandni React, Vite yoki Next project ichida ishlating."}),Ze(r,{name:"tembro.json",status:s?"pass":"fail",message:s?"tembro.json topildi.":`tembro.json topilmadi. Avval ${re("init")} ishlating.`}),s){let d=s.alias??"@",{componentsRoot:l,uiPath:u,libPath:h,hooksPath:p}=sw(s),f=s.cssPath??"src/index.css",b=[["components",l],["ui",u],["lib",h],["hooks",p]].filter(([,C])=>{let M=FP(e,C);return !M||!mt.default.existsSync(M)});Ze(r,{name:"paths",status:b.length?"warn":"pass",message:b.length?`Yetishmayotgan pathlar: ${b.map(([C,M])=>`${C}=${M}`).join(", ")}`:"Configured source paths mavjud."}),Ze(r,{name:"alias",status:iw(e,d)||ow(e,d)?"pass":"warn",message:iw(e,d)||ow(e,d)?`${d} alias tsconfig yoki vite configda topildi.`:`${d} alias topilmadi. Import pathlar ishlamasligi mumkin.`});let y=nw(L__default.default.join(e,f)),w=LP(y);Ze(r,{name:"theme-css",status:w?"pass":"warn",message:w?`${f} ichida Tembro tokenlari bor.`:`${f} ichida Tembro tokenlari topilmadi. ${re(`theme ${f}`)} ishlating.`});let S=qP(e,s);Ze(r,{name:"component-files",status:S.missingFiles.length?"warn":"pass",message:S.missingFiles.length?`Yetishmayotgan component fayllari: ${S.missingFiles.slice(0,8).join(", ")}${S.missingFiles.length>8?` (+${S.missingFiles.length-8})`:""}`:`${S.copiedItems.length} ta copied component file set tekshirildi.`}),Ze(r,{name:"registry-dependencies",status:S.missingRegistryDependencies.length?"warn":"pass",message:S.missingRegistryDependencies.length?`Yetishmayotgan registry dependencylar: ${S.missingRegistryDependencies.slice(0,8).join(", ")}${S.missingRegistryDependencies.length>8?` (+${S.missingRegistryDependencies.length-8})`:""}`:"Copied componentlar uchun registry dependencylar joyida."}),Ze(r,{name:"component-dependencies",status:S.missingPackages.length?"warn":"pass",message:S.missingPackages.length?`Copied componentlar uchun yetishmayotgan package dependencylar: ${S.missingPackages.join(", ")}`:"Copied component package dependencylari package.json ichida bor."});}if(n){let d=aw(e,["@fontsource-variable/geist","clsx","tailwind-merge","tw-animate-css"]);Ze(r,{name:"base-dependencies",status:d.length?"warn":"pass",message:d.length?`Yetishmayotgan dependencylar: ${d.join(", ")}`:"Base dependencylar package.json ichida bor."});}let a=r.filter(d=>d.status==="fail"),c=r.filter(d=>d.status==="warn");if(t.json){console.log(JSON.stringify({ok:a.length===0,checks:r},null,2));return}for(let d of r){let l=`${d.status.toUpperCase()} ${d.name}: ${d.message}`;d.status==="pass"&&x.success(l),d.status==="warn"&&x.warn(l),d.status==="fail"&&x.error(l);}if(a.length&&(x.error(`Doctor failed: ${a.length} fail, ${c.length} warn.`),process.exit(1)),c.length){x.warn(`Doctor completed with ${c.length} warning.`);return}x.success("Doctor passed. Project Tembro setup looks ready.");}var Ka=be(qe());async function lw(t){let e=process.cwd(),r=L__default.default.join(e,"tembro.json"),i=Ka.default.existsSync(r)?await Ka.default.readJson(r):{},o=t??i.cssPath??i.globalCssPath??"src/index.css",n=i.paths?.components??i.componentsPath??"src/components",s=await Mo({cwd:e,cssPath:o,componentsPath:n});x.success(`Tembro theme CSS yangilandi: ${s}`);}var dw={minimal:["button","input","card","badge"],dashboard:["button","input","card","badge","dropdown-menu","skeleton","tabs","page-state","filter-bar","description-list","info-card","data-table"]};async function uw(t,e={}){let r=dw[t];r||(x.error(`Preset topilmadi: ${t}`),process.exit(1)),await Dt(r,e);}var Qe=new $t;Qe.name("tembro").description("Tembro source-copy CLI").version("4.0.
|
|
2005
|
+
Usage:`),console.log(` ${re("add button input data-table")}`),console.log(` ${re("add form --overwrite")}`),console.log(` ${re("list --category data-table")}`),console.log(` ${re("list --json")}`);}var mt=be(qe());function Ja(t){try{return mt.default.readJsonSync(t)}catch{return null}}function nw(t){try{return mt.default.readFileSync(t,"utf8")}catch{return null}}function FP(t,e){return e?L__default.default.resolve(t,e):null}function sw(t){let e=t.paths?.components??t.componentsPath??"src/components",r=t.paths?.ui??t.componentsPath??L__default.default.join(e,"ui"),i=t.paths?.lib??L__default.default.dirname(t.utilsPath??"src/lib/utils.ts"),o=t.paths?.hooks??"src/hooks",n=t.utilsPath??L__default.default.join(i,"utils.ts");return {componentsRoot:e,uiPath:r,libPath:i,hooksPath:o,utilsPath:n}}function jP(t,e){let r=sw(e);return t.replace("{components}",r.componentsRoot).replace("{ui}",r.uiPath).replace("{hooks}",r.hooksPath).replace("{lib}",r.libPath).replace("{utils}",r.utilsPath)}function iw(t,e){return ["tsconfig.app.json","tsconfig.json"].map(i=>L__default.default.join(t,i)).some(i=>!!Ja(i)?.compilerOptions?.paths?.[`${e}/*`])}function ow(t,e){return ["vite.config.ts","vite.config.js","vite.config.mjs"].map(i=>L__default.default.join(t,i)).some(i=>{let o=nw(i);return !!(o?.includes(`"${e}"`)||o?.includes(`'${e}'`))})}function aw(t,e){let r=Ja(L__default.default.join(t,"package.json")),i=new Set([...Object.keys(r?.dependencies??{}),...Object.keys(r?.devDependencies??{})]);return e.filter(o=>!i.has(o))}function Ya(t,e){return (t.files??[]).map(r=>({source:r.source,target:jP(r.target,e)}))}function NP(t,e){return At.map(r=>R[r]).filter(r=>r.category!=="lib").filter(r=>!r.migrationAliasFor).filter(r=>r.files?.length).filter(r=>Ya(r,e).some(i=>mt.default.existsSync(L__default.default.join(t,i.target))))}function qP(t,e){let r=NP(t,e),i=[],o=[],n=new Set;for(let s of r){for(let a of Ya(s,e))mt.default.existsSync(L__default.default.join(t,a.target))||i.push(`${s.name}: ${a.target}`);for(let a of s.registryDependencies??[]){let c=R[a];if(!c?.files?.length)continue;Ya(c,e).some(l=>mt.default.existsSync(L__default.default.join(t,l.target)))||o.push(`${s.name} -> ${a}`);}for(let a of s.dependencies??[])n.add(a);}return {copiedItems:r,missingFiles:i,missingRegistryDependencies:o,missingPackages:aw(t,Array.from(n).sort())}}function Ze(t,e){t.push(e);}function LP(t){return t?t.includes("/* tembro:start */")||t.includes("--aui-")||t.includes("--az-"):false}function cw(t={}){let e=process.cwd(),r=[],i=L__default.default.join(e,"package.json"),o=L__default.default.join(e,"tembro.json"),n=mt.default.existsSync(i),s=Ja(o);if(Ze(r,{name:"package.json",status:n?"pass":"fail",message:n?"package.json topildi.":"package.json topilmadi. Commandni React, Vite yoki Next project ichida ishlating."}),Ze(r,{name:"tembro.json",status:s?"pass":"fail",message:s?"tembro.json topildi.":`tembro.json topilmadi. Avval ${re("init")} ishlating.`}),s){let d=s.alias??"@",{componentsRoot:l,uiPath:u,libPath:h,hooksPath:p}=sw(s),f=s.cssPath??"src/index.css",b=[["components",l],["ui",u],["lib",h],["hooks",p]].filter(([,C])=>{let M=FP(e,C);return !M||!mt.default.existsSync(M)});Ze(r,{name:"paths",status:b.length?"warn":"pass",message:b.length?`Yetishmayotgan pathlar: ${b.map(([C,M])=>`${C}=${M}`).join(", ")}`:"Configured source paths mavjud."}),Ze(r,{name:"alias",status:iw(e,d)||ow(e,d)?"pass":"warn",message:iw(e,d)||ow(e,d)?`${d} alias tsconfig yoki vite configda topildi.`:`${d} alias topilmadi. Import pathlar ishlamasligi mumkin.`});let y=nw(L__default.default.join(e,f)),w=LP(y);Ze(r,{name:"theme-css",status:w?"pass":"warn",message:w?`${f} ichida Tembro tokenlari bor.`:`${f} ichida Tembro tokenlari topilmadi. ${re(`theme ${f}`)} ishlating.`});let S=qP(e,s);Ze(r,{name:"component-files",status:S.missingFiles.length?"warn":"pass",message:S.missingFiles.length?`Yetishmayotgan component fayllari: ${S.missingFiles.slice(0,8).join(", ")}${S.missingFiles.length>8?` (+${S.missingFiles.length-8})`:""}`:`${S.copiedItems.length} ta copied component file set tekshirildi.`}),Ze(r,{name:"registry-dependencies",status:S.missingRegistryDependencies.length?"warn":"pass",message:S.missingRegistryDependencies.length?`Yetishmayotgan registry dependencylar: ${S.missingRegistryDependencies.slice(0,8).join(", ")}${S.missingRegistryDependencies.length>8?` (+${S.missingRegistryDependencies.length-8})`:""}`:"Copied componentlar uchun registry dependencylar joyida."}),Ze(r,{name:"component-dependencies",status:S.missingPackages.length?"warn":"pass",message:S.missingPackages.length?`Copied componentlar uchun yetishmayotgan package dependencylar: ${S.missingPackages.join(", ")}`:"Copied component package dependencylari package.json ichida bor."});}if(n){let d=aw(e,["@fontsource-variable/geist","clsx","tailwind-merge","tw-animate-css"]);Ze(r,{name:"base-dependencies",status:d.length?"warn":"pass",message:d.length?`Yetishmayotgan dependencylar: ${d.join(", ")}`:"Base dependencylar package.json ichida bor."});}let a=r.filter(d=>d.status==="fail"),c=r.filter(d=>d.status==="warn");if(t.json){console.log(JSON.stringify({ok:a.length===0,checks:r},null,2));return}for(let d of r){let l=`${d.status.toUpperCase()} ${d.name}: ${d.message}`;d.status==="pass"&&x.success(l),d.status==="warn"&&x.warn(l),d.status==="fail"&&x.error(l);}if(a.length&&(x.error(`Doctor failed: ${a.length} fail, ${c.length} warn.`),process.exit(1)),c.length){x.warn(`Doctor completed with ${c.length} warning.`);return}x.success("Doctor passed. Project Tembro setup looks ready.");}var Ka=be(qe());async function lw(t){let e=process.cwd(),r=L__default.default.join(e,"tembro.json"),i=Ka.default.existsSync(r)?await Ka.default.readJson(r):{},o=t??i.cssPath??i.globalCssPath??"src/index.css",n=i.paths?.components??i.componentsPath??"src/components",s=await Mo({cwd:e,cssPath:o,componentsPath:n});x.success(`Tembro theme CSS yangilandi: ${s}`);}var dw={minimal:["button","input","card","badge"],dashboard:["button","input","card","badge","dropdown-menu","skeleton","tabs","page-state","filter-bar","description-list","info-card","data-table"]};async function uw(t,e={}){let r=dw[t];r||(x.error(`Preset topilmadi: ${t}`),process.exit(1)),await Dt(r,e);}var Qe=new $t;Qe.name("tembro").description("Tembro source-copy CLI").version("4.0.1");Qe.command("init").description("Initialize local Tembro source files in your project").option("--template <template>","Project defaults: vite or next").option("--skip-install","Do not install base dependencies").option("--showcase","Add every component and write a local Tembro workbench").option("-y, --defaults","Use template defaults without interactive prompts").action(Ky);Qe.command("preset").description("Add a source-copy preset to your project").argument("<name>","preset name: minimal or dashboard").option("-o, --overwrite","overwrite existing files").option("--dry-run","show files without writing").option("--skip-install","do not install package dependencies").action(uw);Qe.command("list").description("List available registry components").option("--category <category>","Filter by registry category").option("--status <status>","Filter by status: stable, preview, experimental, internal").option("--json","Print machine-readable JSON").action(rw);Qe.command("doctor").description("Check local project setup for Tembro source-copy usage").option("--json","Print machine-readable JSON").action(cw);Qe.command("add").description("Copy component source files into your project").argument("[components...]","components to add").option("-o, --overwrite","overwrite existing files").option("--dry-run","show files without writing").option("--plan","print machine-readable copy plan without writing").option("--skip-install","do not install package dependencies").action(Dt);Qe.command("showcase").description("Add every component and write a local Tembro workbench").option("-o, --overwrite","overwrite existing files").option("--dry-run","show files without writing").option("--skip-install","do not install package dependencies").action(t=>Dt(["showcase"],t));Qe.command("theme").description("Write or update Tembro theme CSS in your global CSS file").argument("[cssPath]","global CSS path, default from tembro.json or src/index.css").action(lw);Qe.parse();
|
|
@@ -36,6 +36,8 @@ export type ChartSeries = {
|
|
|
36
36
|
color?: string
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
export type ChartCurve = "linear" | "monotone" | "natural" | "step"
|
|
40
|
+
|
|
39
41
|
export type ChartAxisLabel = string | number | React.ReactNode
|
|
40
42
|
export type ChartSize = "sm" | "md" | "lg"
|
|
41
43
|
export type ChartState = "ready" | "loading" | "empty"
|
|
@@ -77,6 +79,18 @@ function ChartDataTable({ data, valueFormatter, caption }: { data: ChartDatum[];
|
|
|
77
79
|
)
|
|
78
80
|
}
|
|
79
81
|
|
|
82
|
+
function ChartSeriesDataTable({ labels, series, valueFormatter, caption }: { labels: ChartAxisLabel[]; series: ChartSeries[]; valueFormatter?: (value: number) => React.ReactNode; caption: string }) {
|
|
83
|
+
return (
|
|
84
|
+
<div className="sr-only">
|
|
85
|
+
<table>
|
|
86
|
+
<caption>{caption}</caption>
|
|
87
|
+
<thead><tr><th scope="col">Label</th>{series.map((item) => <th scope="col" key={item.key}>{item.label}</th>)}</tr></thead>
|
|
88
|
+
<tbody>{labels.map((label, index) => <tr key={index}><th scope="row">{label}</th>{series.map((item) => <td key={item.key}>{formatChartValue(item.data[index] ?? 0, valueFormatter)}</td>)}</tr>)}</tbody>
|
|
89
|
+
</table>
|
|
90
|
+
</div>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
80
94
|
export type ChartTooltipContentProps = {
|
|
81
95
|
active?: boolean
|
|
82
96
|
label?: React.ReactNode
|
|
@@ -129,7 +143,8 @@ function ChartFrame({ title, description, action, state = "ready", emptyLabel =
|
|
|
129
143
|
}
|
|
130
144
|
|
|
131
145
|
export type BarChartProps = React.ComponentProps<"div"> & {
|
|
132
|
-
data
|
|
146
|
+
data?: ChartDatum[]
|
|
147
|
+
series?: ChartSeries[]
|
|
133
148
|
size?: ChartSize
|
|
134
149
|
max?: number
|
|
135
150
|
showLabels?: boolean
|
|
@@ -142,13 +157,23 @@ export type BarChartProps = React.ComponentProps<"div"> & {
|
|
|
142
157
|
barClassName?: string
|
|
143
158
|
domain?: ChartDomain
|
|
144
159
|
ariaLabel?: string
|
|
160
|
+
stacked?: boolean
|
|
161
|
+
showLegend?: boolean
|
|
162
|
+
barRadius?: number
|
|
145
163
|
}
|
|
146
164
|
|
|
147
|
-
function BarChart({ data, size = "md", max, showLabels = true, showValues = false, showGrid = true, showTooltip = true, valueFormatter, state = "ready", emptyLabel = "No chart data.", barClassName, domain, ariaLabel = "Bar chart", className, ...props }: BarChartProps) {
|
|
165
|
+
function BarChart({ data = [], series, size = "md", max, showLabels = true, showValues = false, showGrid = true, showTooltip = true, valueFormatter, state = "ready", emptyLabel = "No chart data.", barClassName, domain, ariaLabel = "Bar chart", stacked = false, showLegend = Boolean(series?.length), barRadius = 6, className, ...props }: BarChartProps) {
|
|
148
166
|
const height = chartHeightBySize[size]
|
|
149
|
-
const
|
|
167
|
+
const activeSeries = series?.length ? series : [{ key: "value", label: "Value", data: data.map((item) => item.value) }]
|
|
168
|
+
const itemCount = Math.max(data.length, ...activeSeries.map((item) => item.data.length))
|
|
169
|
+
const status = state === "ready" && itemCount === 0 ? "empty" : state
|
|
150
170
|
if (status !== "ready") return <ChartStatus state={status} emptyLabel={emptyLabel} height={height} />
|
|
151
|
-
const
|
|
171
|
+
const labels = Array.from({ length: itemCount }, (_, index) => data[index]?.label ?? `Item ${index + 1}`)
|
|
172
|
+
const chartData = labels.map((label, index) => Object.fromEntries([
|
|
173
|
+
["name", toText(label, `Item ${index + 1}`)],
|
|
174
|
+
["originalLabel", label],
|
|
175
|
+
...activeSeries.map((item) => [item.key, item.data[index] ?? 0]),
|
|
176
|
+
]))
|
|
152
177
|
const resolvedDomain: ChartDomain = domain ?? (max !== undefined ? ["auto", max] : ["auto", "auto"])
|
|
153
178
|
|
|
154
179
|
return (
|
|
@@ -160,19 +185,23 @@ function BarChart({ data, size = "md", max, showLabels = true, showValues = fals
|
|
|
160
185
|
<XAxis dataKey="name" hide={!showLabels} axisLine={false} tickLine={false} tick={{ fill: "var(--muted-foreground)", fontSize: 12 }} interval="preserveStartEnd" />
|
|
161
186
|
<YAxis hide domain={resolvedDomain} />
|
|
162
187
|
{showTooltip ? <RechartsTooltip cursor={{ fill: "var(--muted)", opacity: 0.35 }} content={<ChartTooltipContent valueFormatter={valueFormatter} />} /> : null}
|
|
163
|
-
|
|
164
|
-
{
|
|
165
|
-
|
|
188
|
+
{activeSeries.map((item, seriesIndex) => (
|
|
189
|
+
<Bar key={item.key} dataKey={item.key} name={toText(item.label, item.key)} fill={getChartColor(seriesIndex, item.color)} stackId={stacked ? "total" : undefined} radius={[barRadius, barRadius, 2, 2]} className={barClassName} isAnimationActive={false} label={showValues && (!stacked || seriesIndex === activeSeries.length - 1) ? { position: "top", fill: "var(--muted-foreground)", fontSize: 11, formatter: (value: unknown) => String(formatChartValue(Number(value), valueFormatter)) } : false}>
|
|
190
|
+
{!series?.length ? data.map((datum, index) => <Cell key={index} fill={getChartColor(index, datum.color)} />) : null}
|
|
191
|
+
</Bar>
|
|
192
|
+
))}
|
|
166
193
|
</RechartsBarChart>
|
|
167
194
|
</ResponsiveContainer>
|
|
168
195
|
</div>
|
|
169
|
-
<
|
|
196
|
+
{showLegend && activeSeries.length > 1 ? <ChartLegend className="mt-3" data={activeSeries.map((item, index) => ({ label: item.label, value: 0, color: getChartColor(index, item.color) }))} /> : null}
|
|
197
|
+
{series?.length ? <ChartSeriesDataTable labels={labels} series={activeSeries} valueFormatter={valueFormatter} caption={ariaLabel} /> : <ChartDataTable data={data} valueFormatter={valueFormatter} caption={ariaLabel} />}
|
|
170
198
|
</div>
|
|
171
199
|
)
|
|
172
200
|
}
|
|
173
201
|
|
|
174
202
|
export type LineChartProps = Omit<React.ComponentProps<"div">, "children"> & {
|
|
175
|
-
values
|
|
203
|
+
values?: number[]
|
|
204
|
+
series?: ChartSeries[]
|
|
176
205
|
size?: ChartSize
|
|
177
206
|
width?: number
|
|
178
207
|
height?: number
|
|
@@ -187,13 +216,22 @@ export type LineChartProps = Omit<React.ComponentProps<"div">, "children"> & {
|
|
|
187
216
|
emptyLabel?: React.ReactNode
|
|
188
217
|
domain?: ChartDomain
|
|
189
218
|
ariaLabel?: string
|
|
219
|
+
curve?: ChartCurve
|
|
220
|
+
showDots?: boolean
|
|
221
|
+
showLegend?: boolean
|
|
222
|
+
gradient?: boolean
|
|
223
|
+
strokeWidth?: number
|
|
190
224
|
}
|
|
191
225
|
|
|
192
|
-
function LineChart({ values, size = "md", width = 560, height: heightProp, showArea = false, showGrid = true, showAxis = false, showTooltip = true, labels, valueFormatter, stroke = "var(--primary)", state = "ready", emptyLabel = "No line data.", domain = ["auto", "auto"], ariaLabel = showArea ? "Area chart" : "Line chart", className, style, ...props }: LineChartProps) {
|
|
226
|
+
function LineChart({ values = [], series, size = "md", width = 560, height: heightProp, showArea = false, showGrid = true, showAxis = false, showTooltip = true, labels, valueFormatter, stroke = "var(--primary)", state = "ready", emptyLabel = "No line data.", domain = ["auto", "auto"], ariaLabel = showArea ? "Area chart" : "Line chart", curve = "monotone", showDots = !showArea, showLegend = Boolean(series?.length), gradient = showArea, strokeWidth = 2.5, className, style, ...props }: LineChartProps) {
|
|
193
227
|
const height = heightProp ?? chartHeightBySize[size]
|
|
194
|
-
const
|
|
228
|
+
const gradientId = React.useId().replace(/:/g, "")
|
|
229
|
+
const activeSeries = series?.length ? series : [{ key: "value", label: "Value", data: values, color: stroke }]
|
|
230
|
+
const itemCount = Math.max(...activeSeries.map((item) => item.data.length), 0)
|
|
231
|
+
const status = state === "ready" && itemCount === 0 ? "empty" : state
|
|
195
232
|
if (status !== "ready") return <ChartStatus state={status} emptyLabel={emptyLabel} height={height} />
|
|
196
|
-
const
|
|
233
|
+
const resolvedLabels = Array.from({ length: itemCount }, (_, index) => labels?.[index] ?? String(index + 1))
|
|
234
|
+
const data = resolvedLabels.map((label, index) => Object.fromEntries([["name", toText(label, String(index + 1))], ["originalLabel", label], ...activeSeries.map((item) => [item.key, item.data[index] ?? 0])]))
|
|
197
235
|
const Engine = showArea ? RechartsAreaChart : RechartsLineChart
|
|
198
236
|
|
|
199
237
|
return (
|
|
@@ -201,22 +239,24 @@ function LineChart({ values, size = "md", width = 560, height: heightProp, showA
|
|
|
201
239
|
<div style={{ height }}>
|
|
202
240
|
<ResponsiveContainer width="100%" height="100%" minWidth={1} minHeight={1}>
|
|
203
241
|
<Engine data={data} margin={{ top: 10, right: 10, bottom: showAxis ? 8 : 0, left: showAxis ? -12 : 0 }}>
|
|
242
|
+
{showArea && gradient ? <defs>{activeSeries.map((item, index) => { const color = getChartColor(index, item.color); return <linearGradient key={item.key} id={`${gradientId}-${item.key}`} x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stopColor={color} stopOpacity={0.34} /><stop offset="92%" stopColor={color} stopOpacity={0.02} /></linearGradient> })}</defs> : null}
|
|
204
243
|
{showGrid ? <CartesianGrid vertical={false} stroke="var(--border)" strokeDasharray="4 6" /> : null}
|
|
205
244
|
<XAxis dataKey="name" hide={!showAxis} axisLine={false} tickLine={false} tick={{ fill: "var(--muted-foreground)", fontSize: 12 }} interval="preserveStartEnd" />
|
|
206
245
|
<YAxis hide={!showAxis} domain={domain} axisLine={false} tickLine={false} width={44} tick={{ fill: "var(--muted-foreground)", fontSize: 11 }} />
|
|
207
246
|
{showTooltip ? <RechartsTooltip content={<ChartTooltipContent valueFormatter={valueFormatter} />} /> : null}
|
|
208
|
-
{showArea ? <Area type=
|
|
247
|
+
{activeSeries.map((item, index) => { const color = getChartColor(index, item.color); return showArea ? <Area key={item.key} type={curve} dataKey={item.key} name={toText(item.label, item.key)} stroke={color} strokeWidth={strokeWidth} fill={gradient ? `url(#${gradientId}-${item.key})` : color} fillOpacity={gradient ? 1 : 0.12} dot={showDots ? { r: 3, fill: color, strokeWidth: 2, stroke: "var(--background)" } : false} activeDot={{ r: 5, strokeWidth: 2, stroke: "var(--background)" }} isAnimationActive={false} /> : <Line key={item.key} type={curve} dataKey={item.key} name={toText(item.label, item.key)} stroke={color} strokeWidth={strokeWidth} dot={showDots ? { r: 3, fill: color, strokeWidth: 2, stroke: "var(--background)" } : false} activeDot={{ r: 5, strokeWidth: 2, stroke: "var(--background)" }} isAnimationActive={false} /> })}
|
|
209
248
|
</Engine>
|
|
210
249
|
</ResponsiveContainer>
|
|
211
250
|
</div>
|
|
212
|
-
<
|
|
251
|
+
{showLegend && activeSeries.length > 1 ? <ChartLegend className="mt-3" data={activeSeries.map((item, index) => ({ label: item.label, value: 0, color: getChartColor(index, item.color) }))} /> : null}
|
|
252
|
+
<ChartSeriesDataTable labels={resolvedLabels} series={activeSeries} valueFormatter={valueFormatter} caption={ariaLabel} />
|
|
213
253
|
</div>
|
|
214
254
|
)
|
|
215
255
|
}
|
|
216
256
|
|
|
217
257
|
function AreaChart(props: Omit<LineChartProps, "showArea">) { return <LineChart showArea {...props} /> }
|
|
218
258
|
|
|
219
|
-
export type SparklineProps = Omit<LineChartProps, "size" | "showArea" | "showAxis"> & { values: number[]; positive?: boolean }
|
|
259
|
+
export type SparklineProps = Omit<LineChartProps, "size" | "showArea" | "showAxis" | "series" | "showLegend"> & { values: number[]; positive?: boolean }
|
|
220
260
|
|
|
221
261
|
function Sparkline({ values, positive = true, stroke, className, showTooltip = false, ...props }: SparklineProps) {
|
|
222
262
|
return <LineChart values={values} size="sm" stroke={stroke ?? (positive ? "var(--aui-success,var(--primary))" : "var(--destructive)")} showGrid={false} showAxis={false} showTooltip={showTooltip} className={cn("max-w-44", className)} ariaLabel="Sparkline" {...props} />
|
|
@@ -13,7 +13,7 @@ function WorkspaceLayout({ viewport = true, className, ...props }: WorkspaceLayo
|
|
|
13
13
|
data-viewport={viewport || undefined}
|
|
14
14
|
className={cn(
|
|
15
15
|
"flex min-h-0 min-w-0 bg-[color:var(--aui-page-bg,var(--background))] text-foreground",
|
|
16
|
-
viewport && "h-dvh overflow-hidden",
|
|
16
|
+
viewport && "h-dvh max-h-dvh w-full overflow-hidden overscroll-none",
|
|
17
17
|
className
|
|
18
18
|
)}
|
|
19
19
|
{...props}
|
|
@@ -27,7 +27,7 @@ function WorkspaceContent({ className, ...props }: WorkspaceContentProps) {
|
|
|
27
27
|
return (
|
|
28
28
|
<div
|
|
29
29
|
data-slot="workspace-content"
|
|
30
|
-
className={cn("flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", className)}
|
|
30
|
+
className={cn("isolate flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", className)}
|
|
31
31
|
{...props}
|
|
32
32
|
/>
|
|
33
33
|
)
|
|
@@ -45,7 +45,7 @@ function WorkspaceMain({ scrollable = true, padded = false, className, ...props
|
|
|
45
45
|
data-scrollable={scrollable || undefined}
|
|
46
46
|
className={cn(
|
|
47
47
|
"min-h-0 min-w-0 flex-1",
|
|
48
|
-
scrollable && "overflow-x-hidden overflow-y-auto overscroll-contain",
|
|
48
|
+
scrollable && "overflow-x-hidden overflow-y-auto overscroll-contain [scrollbar-gutter:stable]",
|
|
49
49
|
padded && "p-4 md:p-6",
|
|
50
50
|
className
|
|
51
51
|
)}
|
|
@@ -25,7 +25,7 @@ export function HeroSection() {
|
|
|
25
25
|
<div className="flex flex-wrap gap-2">
|
|
26
26
|
<Button leftIcon={<PlusIcon className="size-4" />}>Create</Button>
|
|
27
27
|
<Button variant="outline" leftIcon={<SettingsIcon className="size-4" />}>Settings</Button>
|
|
28
|
-
<CopyButton value="npx tembro@4.0.
|
|
28
|
+
<CopyButton value="npx tembro@4.0.1 list --json">Copy list command</CopyButton>
|
|
29
29
|
</div>
|
|
30
30
|
</div>
|
|
31
31
|
|
|
@@ -33,7 +33,7 @@ export function HeroSection() {
|
|
|
33
33
|
<StatisticCard label="Registry components" value={moduleCount} change="visible below" trend="up" description="tembro add <name>" />
|
|
34
34
|
<StatisticCard label="Local source files" value="152" change="with hooks/lib" trend="up" description="installed by CLI" />
|
|
35
35
|
<StatisticCard label="Categories" value={registryGroups.length} change="all shown" trend="up" description="actions to wizard" />
|
|
36
|
-
<StatisticCard label="Build" value="Pass" change="doctor pass" trend="up" description="tembro@4.0.
|
|
36
|
+
<StatisticCard label="Build" value="Pass" change="doctor pass" trend="up" description="tembro@4.0.1" />
|
|
37
37
|
</StatisticGrid>
|
|
38
38
|
</div>
|
|
39
39
|
</section>
|
|
@@ -128,17 +128,17 @@
|
|
|
128
128
|
--aui-ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
|
129
129
|
--aui-disabled-opacity: 0.52;
|
|
130
130
|
--aui-shadow-xs: 0 1px 2px oklch(0.24 0.02 255 / 5%);
|
|
131
|
-
--aui-shadow-sm: 0 1px
|
|
132
|
-
--aui-shadow-md: 0
|
|
133
|
-
--aui-shadow-lg: 0
|
|
131
|
+
--aui-shadow-sm: 0 1px 2px oklch(0.24 0.02 255 / 6%), 0 1px 6px oklch(0.24 0.02 255 / 4%);
|
|
132
|
+
--aui-shadow-md: 0 10px 28px -12px oklch(0.24 0.02 255 / 18%), 0 2px 8px oklch(0.24 0.02 255 / 5%);
|
|
133
|
+
--aui-shadow-lg: 0 24px 56px -20px oklch(0.24 0.02 255 / 26%), 0 8px 18px oklch(0.24 0.02 255 / 6%);
|
|
134
134
|
--aui-surface-base: var(--background);
|
|
135
135
|
--aui-surface-raised: color-mix(in oklch, var(--background), white 42%);
|
|
136
136
|
--aui-surface-muted: color-mix(in oklch, var(--muted), var(--background) 52%);
|
|
137
137
|
--aui-border-strong: color-mix(in oklch, var(--border), var(--foreground) 7%);
|
|
138
138
|
|
|
139
139
|
--aui-control-radius: var(--aui-radius-control);
|
|
140
|
-
--aui-focus-ring: color-mix(in oklch, var(--ring), transparent
|
|
141
|
-
--aui-focus-ring-soft: color-mix(in oklch, var(--ring), transparent
|
|
140
|
+
--aui-focus-ring: color-mix(in oklch, var(--ring), transparent 22%);
|
|
141
|
+
--aui-focus-ring-soft: color-mix(in oklch, var(--ring), transparent 78%);
|
|
142
142
|
--aui-danger-ring: color-mix(in oklch, var(--destructive), transparent 48%);
|
|
143
143
|
--aui-danger-ring-soft: color-mix(in oklch, var(--destructive), transparent 86%);
|
|
144
144
|
--aui-warning-ring: color-mix(in oklch, var(--aui-warning), transparent 48%);
|
|
@@ -150,13 +150,13 @@
|
|
|
150
150
|
--aui-control-surface-readonly: color-mix(in oklch, var(--muted), var(--background) 78%);
|
|
151
151
|
--aui-control-shadow: var(--aui-shadow-sm);
|
|
152
152
|
--aui-control-border-strong: var(--aui-border-strong);
|
|
153
|
-
--aui-control-hover-border: color-mix(in oklch, var(--ring), transparent
|
|
153
|
+
--aui-control-hover-border: color-mix(in oklch, var(--ring), transparent 42%);
|
|
154
154
|
--aui-control-panel-bg: var(--aui-surface-raised);
|
|
155
155
|
--aui-control-panel-shadow: var(--aui-shadow-md);
|
|
156
156
|
--aui-card-radius: var(--aui-radius-surface);
|
|
157
157
|
--aui-card-border: var(--border);
|
|
158
158
|
--aui-card-shadow: var(--aui-shadow-xs);
|
|
159
|
-
--aui-card-shadow-hover:
|
|
159
|
+
--aui-card-shadow-hover: 0 18px 42px -18px oklch(0.24 0.02 255 / 24%), 0 3px 10px oklch(0.24 0.02 255 / 6%);
|
|
160
160
|
--aui-card-soft-bg: color-mix(in oklch, var(--muted), var(--background) 34%);
|
|
161
161
|
--aui-card-outline-bg: var(--aui-surface-raised);
|
|
162
162
|
--aui-popover-shadow: var(--aui-shadow-lg);
|
|
@@ -234,8 +234,8 @@
|
|
|
234
234
|
--aui-danger: var(--destructive);
|
|
235
235
|
--aui-danger-foreground: oklch(0.19 0.012 255);
|
|
236
236
|
|
|
237
|
-
--aui-focus-ring: color-mix(in oklch, var(--ring), transparent
|
|
238
|
-
--aui-focus-ring-soft: color-mix(in oklch, var(--ring), transparent
|
|
237
|
+
--aui-focus-ring: color-mix(in oklch, var(--ring), transparent 18%);
|
|
238
|
+
--aui-focus-ring-soft: color-mix(in oklch, var(--ring), transparent 72%);
|
|
239
239
|
--aui-danger-ring: color-mix(in oklch, var(--destructive), transparent 46%);
|
|
240
240
|
--aui-danger-ring-soft: color-mix(in oklch, var(--destructive), transparent 84%);
|
|
241
241
|
--aui-warning-ring: color-mix(in oklch, var(--aui-warning), transparent 46%);
|
|
@@ -243,9 +243,9 @@
|
|
|
243
243
|
--aui-radius-control: var(--radius-lg);
|
|
244
244
|
--aui-radius-surface: var(--radius-xl);
|
|
245
245
|
--aui-shadow-xs: 0 1px 2px oklch(0 0 0 / 12%);
|
|
246
|
-
--aui-shadow-sm: 0 1px
|
|
247
|
-
--aui-shadow-md: 0
|
|
248
|
-
--aui-shadow-lg: 0
|
|
246
|
+
--aui-shadow-sm: 0 1px 2px oklch(0 0 0 / 20%), 0 2px 8px oklch(0 0 0 / 12%);
|
|
247
|
+
--aui-shadow-md: 0 16px 36px -16px oklch(0 0 0 / 62%), 0 3px 12px oklch(0 0 0 / 20%);
|
|
248
|
+
--aui-shadow-lg: 0 28px 64px -20px oklch(0 0 0 / 72%), 0 10px 24px oklch(0 0 0 / 24%);
|
|
249
249
|
--aui-surface-base: var(--background);
|
|
250
250
|
--aui-surface-raised: oklch(1 0 0 / 4%);
|
|
251
251
|
--aui-surface-muted: oklch(1 0 0 / 6%);
|
|
@@ -286,7 +286,7 @@
|
|
|
286
286
|
--aui-table-border: oklch(1 0 0 / 8%);
|
|
287
287
|
--aui-table-selection-surface: oklch(1 0 0 / 4%);
|
|
288
288
|
--aui-control-border-strong: var(--aui-border-strong);
|
|
289
|
-
--aui-control-hover-border: color-mix(in oklch, var(--ring), transparent
|
|
289
|
+
--aui-control-hover-border: color-mix(in oklch, var(--ring), transparent 44%);
|
|
290
290
|
--aui-control-panel-bg: var(--aui-surface-raised);
|
|
291
291
|
--aui-control-panel-shadow: var(--aui-shadow-md);
|
|
292
292
|
--aui-button-primary-shadow: 0 1px 0 color-mix(in oklch, white, transparent 82%), 0 18px 40px color-mix(in oklch, var(--primary), transparent 82%);
|
|
@@ -317,6 +317,20 @@
|
|
|
317
317
|
|
|
318
318
|
body {
|
|
319
319
|
@apply bg-background text-foreground antialiased;
|
|
320
|
+
margin: 0;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
html:has([data-slot="workspace-layout"][data-viewport="true"]),
|
|
324
|
+
body:has([data-slot="workspace-layout"][data-viewport="true"]) {
|
|
325
|
+
height: 100%;
|
|
326
|
+
overflow: hidden;
|
|
327
|
+
overscroll-behavior: none;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
body:has([data-slot="workspace-layout"][data-viewport="true"]) > #root {
|
|
331
|
+
height: 100%;
|
|
332
|
+
min-height: 0;
|
|
333
|
+
overflow: hidden;
|
|
320
334
|
}
|
|
321
335
|
}
|
|
322
336
|
|
|
@@ -552,7 +566,9 @@
|
|
|
552
566
|
}
|
|
553
567
|
|
|
554
568
|
[data-slot="button"][data-slot="button"]:focus-visible {
|
|
555
|
-
|
|
569
|
+
position: relative;
|
|
570
|
+
z-index: 1;
|
|
571
|
+
box-shadow: var(--aui-control-shadow), 0 0 0 2px var(--background), 0 0 0 4px var(--aui-focus-ring);
|
|
556
572
|
}
|
|
557
573
|
|
|
558
574
|
[data-slot="button"][data-slot="button"]:not(:disabled):not([aria-disabled="true"]):hover {
|
|
@@ -568,8 +584,9 @@
|
|
|
568
584
|
}
|
|
569
585
|
|
|
570
586
|
[data-slot="button"][data-variant="default"]:not(:disabled):not([aria-disabled="true"]):hover {
|
|
571
|
-
|
|
572
|
-
|
|
587
|
+
border-color: color-mix(in oklch, var(--primary), black 16%);
|
|
588
|
+
background: color-mix(in oklch, var(--primary), white 7%);
|
|
589
|
+
box-shadow: 0 8px 20px -10px color-mix(in oklch, var(--primary), transparent 35%);
|
|
573
590
|
}
|
|
574
591
|
|
|
575
592
|
[data-slot="button"][data-variant="secondary"] {
|
|
@@ -585,7 +602,9 @@
|
|
|
585
602
|
}
|
|
586
603
|
|
|
587
604
|
[data-slot="button"][data-variant="outline"]:not(:disabled):not([aria-disabled="true"]):hover {
|
|
588
|
-
|
|
605
|
+
border-color: var(--aui-control-hover-border);
|
|
606
|
+
background: var(--accent);
|
|
607
|
+
color: var(--accent-foreground);
|
|
589
608
|
}
|
|
590
609
|
|
|
591
610
|
[data-slot="button"][data-variant="ghost"] {
|
|
@@ -596,8 +615,9 @@
|
|
|
596
615
|
}
|
|
597
616
|
|
|
598
617
|
[data-slot="button"][data-variant="ghost"]:not(:disabled):not([aria-disabled="true"]):hover {
|
|
599
|
-
border-color:
|
|
600
|
-
background:
|
|
618
|
+
border-color: transparent;
|
|
619
|
+
background: var(--accent);
|
|
620
|
+
color: var(--accent-foreground);
|
|
601
621
|
}
|
|
602
622
|
|
|
603
623
|
[data-slot="button"][data-variant="destructive"] {
|
|
@@ -688,7 +708,8 @@
|
|
|
688
708
|
[data-slot="input"][data-slot="input"]:focus-visible,
|
|
689
709
|
[data-slot="textarea"][data-slot="textarea"]:focus-visible,
|
|
690
710
|
[data-slot="select-trigger"][data-slot="select-trigger"]:focus-visible {
|
|
691
|
-
|
|
711
|
+
border-color: var(--ring);
|
|
712
|
+
box-shadow: var(--aui-control-shadow), 0 0 0 1px var(--background), 0 0 0 3px var(--aui-focus-ring);
|
|
692
713
|
}
|
|
693
714
|
|
|
694
715
|
[data-slot="input"][data-slot="input"]:disabled,
|
|
@@ -867,7 +888,7 @@
|
|
|
867
888
|
|
|
868
889
|
[data-slot="tabs-trigger"][data-slot="tabs-trigger"]:hover {
|
|
869
890
|
color: var(--foreground);
|
|
870
|
-
background:
|
|
891
|
+
background: var(--accent);
|
|
871
892
|
}
|
|
872
893
|
|
|
873
894
|
[data-slot="tabs-trigger"][data-slot="tabs-trigger"][data-selected] {
|
|
@@ -878,13 +899,13 @@
|
|
|
878
899
|
}
|
|
879
900
|
|
|
880
901
|
[data-slot="tabs-trigger"][data-slot="tabs-trigger"]:focus-visible {
|
|
881
|
-
box-shadow:
|
|
902
|
+
box-shadow: 0 0 0 2px var(--background), 0 0 0 4px var(--aui-focus-ring);
|
|
882
903
|
}
|
|
883
904
|
|
|
884
905
|
:is([data-slot="card"], [data-card]) {
|
|
885
906
|
border: 1px solid var(--aui-card-border);
|
|
886
907
|
border-radius: var(--aui-card-radius);
|
|
887
|
-
background:
|
|
908
|
+
background: var(--card);
|
|
888
909
|
box-shadow: var(--aui-card-shadow);
|
|
889
910
|
}
|
|
890
911
|
|
|
@@ -945,6 +966,7 @@
|
|
|
945
966
|
:is([data-slot="card"], [data-card])[data-interactive="true"]:hover {
|
|
946
967
|
border-color: var(--aui-control-hover-border);
|
|
947
968
|
box-shadow: var(--aui-card-shadow-hover);
|
|
969
|
+
transform: translateY(-1px);
|
|
948
970
|
}
|
|
949
971
|
|
|
950
972
|
:is([data-slot="card"], [data-card])[data-interactive="true"]:focus-visible {
|