@uselets/ui 1.14.0 → 1.15.0
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/README.md +34 -7
- package/dist/cli/uselets.mjs +4 -4
- package/dist/cli/uselets.mjs.map +1 -1
- package/dist/components/slider.js +1 -1
- package/dist/components/slider.js.map +1 -1
- package/dist/components/theme.d.ts +2 -1
- package/dist/components/theme.js +1 -1
- package/dist/components/theme.js.map +1 -1
- package/dist/components/toggle-group.js +1 -1
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.d.ts +1 -1
- package/dist/components/toggle.js +1 -1
- package/dist/components/toggle.js.map +1 -1
- package/dist/skills/uselets-ui/SKILL.md +4 -2
- package/dist/skills/uselets-ui/references/component-catalog.md +2 -1
- package/dist/skills/uselets-ui/references/package-guide.md +13 -6
- package/package.json +12 -12
- package/skills/uselets-ui/SKILL.md +4 -2
- package/skills/uselets-ui/references/component-catalog.md +2 -1
- package/skills/uselets-ui/references/package-guide.md +13 -6
package/README.md
CHANGED
|
@@ -53,10 +53,15 @@ bun uselets init
|
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
The command asks which theme to import, asks for your global CSS path with `src/styles/globals.css` as the
|
|
56
|
-
default, and optionally installs the agent skill.
|
|
56
|
+
default, and optionally installs the agent skill. It also imports the Inter font: it detects a conventional
|
|
57
|
+
app entry file (`app/layout.tsx`, `pages/_app.tsx`, `src/main.tsx`, `src/index.tsx`, and `.jsx` variants) and
|
|
58
|
+
inserts `import '@fontsource-variable/inter'` there, or asks for the entry file path when none is found. This
|
|
59
|
+
avoids `@import '@fontsource-variable/inter'` in the global CSS, which some bundlers (including Next.js) don't
|
|
60
|
+
resolve correctly for third-party CSS — import it as a JS module instead. For non-interactive setup, pass
|
|
61
|
+
options:
|
|
57
62
|
|
|
58
63
|
```bash
|
|
59
|
-
bun uselets init --theme max --css src/styles/globals.css --no-install-skill
|
|
64
|
+
bun uselets init --theme max --css src/styles/globals.css --entry app/layout.tsx --no-install-skill
|
|
60
65
|
```
|
|
61
66
|
|
|
62
67
|
## Tailwind CSS v4 setup
|
|
@@ -76,13 +81,12 @@ npm install tailwindcss @tailwindcss/postcss
|
|
|
76
81
|
export { default } from '@uselets/ui/postcss.config'
|
|
77
82
|
```
|
|
78
83
|
|
|
79
|
-
3. Import Tailwind
|
|
84
|
+
3. Import Tailwind and one package theme in your global stylesheet:
|
|
80
85
|
|
|
81
86
|
```css
|
|
82
87
|
/* app.css */
|
|
83
88
|
@import 'tailwindcss';
|
|
84
89
|
@import '@uselets/ui/themes/max.css';
|
|
85
|
-
@import '@fontsource-variable/inter';
|
|
86
90
|
```
|
|
87
91
|
|
|
88
92
|
Use `@uselets/ui/themes/gomax.css` instead for GoMax apps. If your app consumes `@uselets/ui` components, add a
|
|
@@ -92,17 +96,25 @@ source directive so Tailwind can generate classes used by the package:
|
|
|
92
96
|
@source '../node_modules/@uselets/ui/dist';
|
|
93
97
|
```
|
|
94
98
|
|
|
99
|
+
4. Import the Inter font once from your app's entry file (not from CSS — bundlers such as Next.js don't
|
|
100
|
+
resolve third-party CSS `@import`s reliably):
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
// app/layout.tsx (or src/main.tsx, pages/_app.tsx, ...)
|
|
104
|
+
import '@fontsource-variable/inter'
|
|
105
|
+
```
|
|
106
|
+
|
|
95
107
|
## Quick start
|
|
96
108
|
|
|
97
|
-
1. Import one package theme once in your global stylesheet:
|
|
109
|
+
1. Import Tailwind and one package theme once in your global stylesheet:
|
|
98
110
|
|
|
99
111
|
```css
|
|
100
112
|
@import 'tailwindcss';
|
|
101
113
|
@import '@uselets/ui/themes/max.css';
|
|
102
|
-
@import '@fontsource-variable/inter';
|
|
103
114
|
```
|
|
104
115
|
|
|
105
|
-
For GoMax apps, import `@uselets/ui/themes/gomax.css` instead.
|
|
116
|
+
For GoMax apps, import `@uselets/ui/themes/gomax.css` instead. Import the font once from your app's entry
|
|
117
|
+
file, as shown above.
|
|
106
118
|
|
|
107
119
|
2. Import components from the package root:
|
|
108
120
|
|
|
@@ -444,6 +456,21 @@ useHotkeys([
|
|
|
444
456
|
|
|
445
457
|
Utilities are exported from the package root and `@uselets/ui/utils`, including `cn` and `randomId`. The package also exports `composeRefs` (and `setRef`) from `@uselets/ui/lib/compose-refs` for composing multiple refs into a single callback ref — handy when a component needs to merge a forwarded `ref` with an internal one (for example `MaskInput`).
|
|
446
458
|
|
|
459
|
+
`ThemeProvider` stores the active `Theme` (`'dark' | 'light' | 'system'`) in `localStorage` under `storageKey` (default `'vite-ui-theme'`) and toggles the `dark`/`light` class on `document.documentElement`. Pass `defaultTheme` to set the initial theme when none is stored yet, and `disableTransitionOnChange` to suppress CSS transitions for the moment the class swaps, matching `next-themes`'s prop of the same name:
|
|
460
|
+
|
|
461
|
+
```tsx
|
|
462
|
+
import { ModeToggle, ThemeProvider } from '@uselets/ui/theme'
|
|
463
|
+
|
|
464
|
+
export function AppRoot({ children }: { children: React.ReactNode }) {
|
|
465
|
+
return (
|
|
466
|
+
<ThemeProvider defaultTheme="system" disableTransitionOnChange>
|
|
467
|
+
<ModeToggle />
|
|
468
|
+
{children}
|
|
469
|
+
</ThemeProvider>
|
|
470
|
+
)
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
447
474
|
### Sonner example
|
|
448
475
|
|
|
449
476
|
```tsx
|
package/dist/cli/uselets.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{spawn as e}from"node:child_process";import t from"node:fs/promises";import n from"node:path";import r from"node:readline/promises";import{fileURLToPath as i}from"node:url";import{Command as a,Option as o}from"commander";const s=`uselets-ui`,c={codex:n.join(`.agents`,`skills`,s),claude:n.join(`.claude`,`skills`,s)},
|
|
3
|
-
`),console.log(`Created postcss.config.mjs.`)}function
|
|
2
|
+
import{spawn as e}from"node:child_process";import t from"node:fs/promises";import n from"node:path";import r from"node:readline/promises";import{fileURLToPath as i}from"node:url";import{Command as a,Option as o}from"commander";const s=`uselets-ui`,c=`@fontsource-variable/inter`,l=[`app/layout.tsx`,`app/layout.jsx`,`pages/_app.tsx`,`pages/_app.jsx`,`src/main.tsx`,`src/main.jsx`,`src/index.tsx`,`src/index.jsx`],u={codex:n.join(`.agents`,`skills`,s),claude:n.join(`.claude`,`skills`,s)},d=Object.keys(u);async function f(e){try{return await t.access(e),!0}catch{return!1}}async function p(e){return JSON.parse(await t.readFile(e,`utf8`))}async function m(){let e=i(new URL(`.`,import.meta.url));for(;;)try{return await t.access(n.join(e,`package.json`)),e}catch{let t=n.dirname(e);if(t===e)throw Error(`Unable to resolve @uselets/ui package root`);e=t}}function h(e){return e===`all`?d:[e]}function g(e,t){return!!(e.dependencies?.[t]||e.devDependencies?.[t]||e.peerDependencies?.[t]||e.optionalDependencies?.[t])}async function _(e,t){let r=t.packageManager?.split(`@`)[0];return r===`bun`||r===`pnpm`||r===`yarn`||r===`npm`?r:await f(n.join(e,`bun.lock`))?`bun`:await f(n.join(e,`pnpm-lock.yaml`))?`pnpm`:await f(n.join(e,`yarn.lock`))?`yarn`:(await f(n.join(e,`package-lock.json`)),`npm`)}function v(e,t,n){switch(e){case`bun`:return[`bun`,`add`,...n?[`-d`]:[],...t];case`pnpm`:return[`pnpm`,`add`,...n?[`-D`]:[],...t];case`yarn`:return[`yarn`,`add`,...n?[`-D`]:[],...t];case`npm`:return[`npm`,`install`,...n?[`-D`]:[],...t]}}async function y(t,n){let[r,...i]=t;if(!r)throw Error(`Missing command`);console.log(`Running: ${t.join(` `)}`),await new Promise((t,a)=>{let o=e(r,i,{cwd:n,stdio:`inherit`});o.on(`error`,a),o.on(`close`,e=>{if(e===0){t();return}a(Error(`${r} exited with code ${e}`))})})}function b(e,t){let n=e.dependencies?.[t]??e.devDependencies?.[t];if(!n)throw Error(`Unable to find ${t} version in @uselets/ui package metadata`);return n}async function x(e,t){let r=await m(),i=await p(n.join(r,`package.json`)),a=await _(e,t),o=[],s=[];if(!i.name||!i.version)throw Error(`Unable to resolve @uselets/ui package name and version`);g(t,i.name)||o.push(`${i.name}@${i.version}`),g(t,c)||o.push(`${c}@${b(i,c)}`),g(t,`tailwindcss`)||s.push(`tailwindcss@${b(i,`tailwindcss`)}`),g(t,`@tailwindcss/postcss`)||s.push(`@tailwindcss/postcss@${b(i,`@tailwindcss/postcss`)}`),o.length>0?await y(v(a,o,!1),e):console.log(`Runtime dependencies already declared.`),s.length>0?await y(v(a,s,!0),e):console.log(`Tailwind dependencies already declared.`)}async function S(e){let r=await m(),i=n.join(r,`skills`,s);try{await t.access(i)}catch{throw Error(`Bundled skill not found at ${i}`)}let a=[];for(let r of e){let e=n.join(process.cwd(),u[r]);await t.rm(e,{recursive:!0,force:!0}),await t.mkdir(n.dirname(e),{recursive:!0}),await t.cp(i,e,{recursive:!0}),a.push(e)}console.log(`Installed ${s} skill:`);for(let e of a)console.log(`- ${e}`)}async function C(){return r.createInterface({input:process.stdin,output:process.stdout})}async function w(e){if(!process.stdin.isTTY)return e;let t=await C();try{for(;;){let n=(await t.question(`Theme (max/gomax) [${e}]: `)).trim().toLowerCase();if(!n)return e;if(n===`max`||n===`gomax`)return n;console.log(`Please choose "max" or "gomax".`)}}finally{t.close()}}async function T(e){if(!process.stdin.isTTY)return e;let t=await C();try{return(await t.question(`Global CSS path [${e}]: `)).trim()||e}finally{t.close()}}async function E(){if(!process.stdin.isTTY)return!1;let e=await C();try{for(;;){let t=(await e.question(`Install agent skill? (y/N): `)).trim().toLowerCase();if(!t||t===`n`||t===`no`)return!1;if(t===`y`||t===`yes`)return!0;console.log(`Please answer "y" or "n".`)}}finally{e.close()}}async function D(e){let r=n.join(e,`postcss.config.mjs`);if(await f(r)){console.log(`Preserved existing postcss.config.mjs.`);return}await t.writeFile(r,`export { default } from '@uselets/ui/postcss.config'
|
|
3
|
+
`),console.log(`Created postcss.config.mjs.`)}function O(e){let t=n.posix.dirname(e.replaceAll(n.sep,n.posix.sep)),r=n.posix.relative(t,`node_modules/@uselets/ui/dist`);return r.startsWith(`.`)?r:`./${r}`}function k(e,t,n){let r=[],i=/@import\s+['"]tailwindcss['"]/.test(e),a=/@import\s+['"]@uselets\/ui\/themes\/(?:max|gomax)\.css['"]/.test(e),o=/@source\s+['"][^'"]*@uselets\/ui\/dist['"]/.test(e);return i||r.push(`@import 'tailwindcss';`),a||r.push(`@import '@uselets/ui/themes/${t}.css';`),o||r.push(`@source '${O(n)}';`),{imports:r,hasTheme:a}}async function A(e,r,i){let a=n.resolve(e,r),o=await f(a)?await t.readFile(a,`utf8`):``,{imports:s,hasTheme:c}=k(o,i,r);if(c&&console.log(`Preserved existing @uselets/ui theme import.`),s.length===0){console.log(`Global CSS already configured at ${r}.`);return}let l=o.length>0&&!o.startsWith(`
|
|
4
4
|
`)?`
|
|
5
|
-
`:``,
|
|
6
|
-
`)}${l}${o}`;await t.mkdir(n.dirname(a),{recursive:!0}),await t.writeFile(a,
|
|
5
|
+
`:``,u=`${s.join(`
|
|
6
|
+
`)}${l}${o}`;await t.mkdir(n.dirname(a),{recursive:!0}),await t.writeFile(a,u),console.log(`Updated global CSS at ${r}.`)}async function j(e){for(let t of l)if(await f(n.join(e,t)))return t}async function M(){if(!process.stdin.isTTY)return;let e=await C();try{return(await e.question(`App entry file to import the font in (leave empty to skip): `)).trim()||void 0}finally{e.close()}}async function N(e,t){return t||await j(e)||M()}function P(e){console.log(`${e} Add \`import '${c}'\` to your app's entry file (for example app/layout.tsx or src/main.tsx) to load the font.`)}async function F(e,r){if(!r){P(`Could not detect an app entry file.`);return}let i=n.resolve(e,r);if(!await f(i)){P(`Entry file ${r} not found.`);return}let a=await t.readFile(i,`utf8`);if(RegExp(`import\\s+['"]${c}['"]`).test(a)){console.log(`Font import already present in ${r}.`);return}let o=a.match(/^(['"])use (?:client|server)\1;?\r?\n/),s=`import '${c}'\n`,l=o?a.slice(0,o[0].length)+s+a.slice(o[0].length):s+a;await t.writeFile(i,l),console.log(`Added font import to ${r}.`)}async function I(e){let t=process.cwd(),r=n.join(t,`package.json`);if(!await f(r))throw Error(`No package.json found in the current directory. Run uselets init from your project root.`);let i=await p(r),a=e.theme??await w(`max`),o=e.css??await T(`src/styles/globals.css`),s=await N(t,e.entry),c=e.installSkill??await E();await x(t,i),await D(t),await A(t,o,a),await F(t,s),c&&await S(d)}async function L(){let e=new a;if(e.name(`uselets`).description(`CLI for @uselets/ui`).showHelpAfterError(),e.command(`skill`).description(`Reinstall the ${s} agent skill`).addOption(new o(`--agent <agent>`,`Target agent directory`).choices([`codex`,`claude`,`all`]).default(`all`)).action(async e=>{await S(h(e.agent))}),e.command(`init`).description(`Set up @uselets/ui in this project`).addOption(new o(`--theme <theme>`,`Theme to import`).choices([`max`,`gomax`])).option(`--css <path>`,`Global CSS file path`).option(`--entry <path>`,`App entry file to import the font in (for example app/layout.tsx or src/main.tsx)`).option(`--install-skill`,`Install the agent skill without prompting`).option(`--no-install-skill`,`Skip the agent skill prompt and installation`).action(async e=>{await I(e)}),process.argv.length<=2){e.outputHelp();return}await e.parseAsync()}L().catch(e=>{console.error(e instanceof Error?e.message:e),process.exitCode=1});export{};
|
|
7
7
|
//# sourceMappingURL=uselets.mjs.map
|
package/dist/cli/uselets.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uselets.mjs","names":[],"sources":["../../src/cli/uselets.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { spawn } from 'node:child_process'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport readline from 'node:readline/promises'\nimport { fileURLToPath } from 'node:url'\n\nimport { Command, Option } from 'commander'\n\nconst SKILL_NAME = 'uselets-ui'\nconst DEFAULT_CSS_PATH = 'src/styles/globals.css'\nconst POSTCSS_CONFIG = \"export { default } from '@uselets/ui/postcss.config'\\n\"\nconst AGENT_TARGETS = {\n codex: path.join('.agents', 'skills', SKILL_NAME),\n claude: path.join('.claude', 'skills', SKILL_NAME)\n} as const\n\ntype AgentTarget = keyof typeof AGENT_TARGETS\ntype AgentOption = AgentTarget | 'all'\ntype ThemeOption = 'max' | 'gomax'\ntype PackageManager = 'bun' | 'pnpm' | 'yarn' | 'npm'\ntype PackageJson = {\n name?: string\n version?: string\n packageManager?: string\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n optionalDependencies?: Record<string, string>\n}\ntype InitOptions = {\n theme?: ThemeOption\n css?: string\n installSkill?: boolean\n}\n\nconst ALL_AGENT_TARGETS = Object.keys(AGENT_TARGETS) as AgentTarget[]\n\nasync function pathExists(targetPath: string) {\n try {\n await fs.access(targetPath)\n return true\n } catch {\n return false\n }\n}\n\nasync function readJsonFile<T>(filePath: string) {\n return JSON.parse(await fs.readFile(filePath, 'utf8')) as T\n}\n\nasync function findPackageRoot() {\n let currentDir = fileURLToPath(new URL('.', import.meta.url))\n\n while (true) {\n try {\n await fs.access(path.join(currentDir, 'package.json'))\n return currentDir\n } catch {\n const parentDir = path.dirname(currentDir)\n\n if (parentDir === currentDir) {\n throw new Error('Unable to resolve @uselets/ui package root')\n }\n\n currentDir = parentDir\n }\n }\n}\n\nfunction resolveTargets(agent: AgentOption) {\n return agent === 'all' ? ALL_AGENT_TARGETS : [agent]\n}\n\nfunction hasDependency(packageJson: PackageJson, dependencyName: string) {\n return Boolean(\n packageJson.dependencies?.[dependencyName] ||\n packageJson.devDependencies?.[dependencyName] ||\n packageJson.peerDependencies?.[dependencyName] ||\n packageJson.optionalDependencies?.[dependencyName]\n )\n}\n\nasync function detectPackageManager(projectRoot: string, packageJson: PackageJson): Promise<PackageManager> {\n const declaredManager = packageJson.packageManager?.split('@')[0]\n\n if (\n declaredManager === 'bun' ||\n declaredManager === 'pnpm' ||\n declaredManager === 'yarn' ||\n declaredManager === 'npm'\n ) {\n return declaredManager\n }\n\n if (await pathExists(path.join(projectRoot, 'bun.lock'))) {\n return 'bun'\n }\n\n if (await pathExists(path.join(projectRoot, 'pnpm-lock.yaml'))) {\n return 'pnpm'\n }\n\n if (await pathExists(path.join(projectRoot, 'yarn.lock'))) {\n return 'yarn'\n }\n\n if (await pathExists(path.join(projectRoot, 'package-lock.json'))) {\n return 'npm'\n }\n\n return 'npm'\n}\n\nfunction buildAddCommand(packageManager: PackageManager, dependencies: string[], dev: boolean) {\n switch (packageManager) {\n case 'bun':\n return ['bun', 'add', ...(dev ? ['-d'] : []), ...dependencies]\n case 'pnpm':\n return ['pnpm', 'add', ...(dev ? ['-D'] : []), ...dependencies]\n case 'yarn':\n return ['yarn', 'add', ...(dev ? ['-D'] : []), ...dependencies]\n case 'npm':\n return ['npm', 'install', ...(dev ? ['-D'] : []), ...dependencies]\n }\n}\n\nasync function runCommand(commandParts: string[], cwd: string) {\n const [command, ...args] = commandParts\n\n if (!command) {\n throw new Error('Missing command')\n }\n\n console.log(`Running: ${commandParts.join(' ')}`)\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command, args, { cwd, stdio: 'inherit' })\n\n child.on('error', reject)\n child.on('close', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n\n reject(new Error(`${command} exited with code ${code}`))\n })\n })\n}\n\nfunction getPackageVersion(packageJson: PackageJson, dependencyName: string) {\n const version = packageJson.dependencies?.[dependencyName] ?? packageJson.devDependencies?.[dependencyName]\n\n if (!version) {\n throw new Error(`Unable to find ${dependencyName} version in @uselets/ui package metadata`)\n }\n\n return version\n}\n\nasync function installMissingDependencies(projectRoot: string, projectPackageJson: PackageJson) {\n const packageRoot = await findPackageRoot()\n const packageJson = await readJsonFile<PackageJson>(path.join(packageRoot, 'package.json'))\n const packageManager = await detectPackageManager(projectRoot, projectPackageJson)\n const runtimeDependencies = []\n const devDependencies = []\n\n if (!packageJson.name || !packageJson.version) {\n throw new Error('Unable to resolve @uselets/ui package name and version')\n }\n\n if (!hasDependency(projectPackageJson, packageJson.name)) {\n runtimeDependencies.push(`${packageJson.name}@${packageJson.version}`)\n }\n\n if (!hasDependency(projectPackageJson, '@fontsource-variable/inter')) {\n runtimeDependencies.push(\n `@fontsource-variable/inter@${getPackageVersion(packageJson, '@fontsource-variable/inter')}`\n )\n }\n\n if (!hasDependency(projectPackageJson, 'tailwindcss')) {\n devDependencies.push(`tailwindcss@${getPackageVersion(packageJson, 'tailwindcss')}`)\n }\n\n if (!hasDependency(projectPackageJson, '@tailwindcss/postcss')) {\n devDependencies.push(`@tailwindcss/postcss@${getPackageVersion(packageJson, '@tailwindcss/postcss')}`)\n }\n\n if (runtimeDependencies.length > 0) {\n await runCommand(buildAddCommand(packageManager, runtimeDependencies, false), projectRoot)\n } else {\n console.log('Runtime dependencies already declared.')\n }\n\n if (devDependencies.length > 0) {\n await runCommand(buildAddCommand(packageManager, devDependencies, true), projectRoot)\n } else {\n console.log('Tailwind dependencies already declared.')\n }\n}\n\nasync function installSkill(targets: AgentTarget[]) {\n const packageRoot = await findPackageRoot()\n const sourcePath = path.join(packageRoot, 'skills', SKILL_NAME)\n\n try {\n await fs.access(sourcePath)\n } catch {\n throw new Error(`Bundled skill not found at ${sourcePath}`)\n }\n\n const installedPaths = []\n\n for (const target of targets) {\n const targetPath = path.join(process.cwd(), AGENT_TARGETS[target])\n\n await fs.rm(targetPath, { recursive: true, force: true })\n await fs.mkdir(path.dirname(targetPath), { recursive: true })\n await fs.cp(sourcePath, targetPath, { recursive: true })\n\n installedPaths.push(targetPath)\n }\n\n console.log(`Installed ${SKILL_NAME} skill:`)\n\n for (const installedPath of installedPaths) {\n console.log(`- ${installedPath}`)\n }\n}\n\nasync function createPrompt() {\n return readline.createInterface({ input: process.stdin, output: process.stdout })\n}\n\nasync function promptTheme(defaultTheme: ThemeOption) {\n if (!process.stdin.isTTY) {\n return defaultTheme\n }\n\n const prompt = await createPrompt()\n\n try {\n while (true) {\n const answer = (await prompt.question(`Theme (max/gomax) [${defaultTheme}]: `)).trim().toLowerCase()\n\n if (!answer) {\n return defaultTheme\n }\n\n if (answer === 'max' || answer === 'gomax') {\n return answer\n }\n\n console.log('Please choose \"max\" or \"gomax\".')\n }\n } finally {\n prompt.close()\n }\n}\n\nasync function promptCssPath(defaultCssPath: string) {\n if (!process.stdin.isTTY) {\n return defaultCssPath\n }\n\n const prompt = await createPrompt()\n\n try {\n const answer = (await prompt.question(`Global CSS path [${defaultCssPath}]: `)).trim()\n return answer || defaultCssPath\n } finally {\n prompt.close()\n }\n}\n\nasync function promptInstallSkill() {\n if (!process.stdin.isTTY) {\n return false\n }\n\n const prompt = await createPrompt()\n\n try {\n while (true) {\n const answer = (await prompt.question('Install agent skill? (y/N): ')).trim().toLowerCase()\n\n if (!answer || answer === 'n' || answer === 'no') {\n return false\n }\n\n if (answer === 'y' || answer === 'yes') {\n return true\n }\n\n console.log('Please answer \"y\" or \"n\".')\n }\n } finally {\n prompt.close()\n }\n}\n\nasync function ensurePostcssConfig(projectRoot: string) {\n const postcssPath = path.join(projectRoot, 'postcss.config.mjs')\n\n if (await pathExists(postcssPath)) {\n console.log('Preserved existing postcss.config.mjs.')\n return\n }\n\n await fs.writeFile(postcssPath, POSTCSS_CONFIG)\n console.log('Created postcss.config.mjs.')\n}\n\nfunction buildPackageSource(cssPath: string) {\n const cssDir = path.posix.dirname(cssPath.replaceAll(path.sep, path.posix.sep))\n const relativeSource = path.posix.relative(cssDir, 'node_modules/@uselets/ui/dist')\n\n return relativeSource.startsWith('.') ? relativeSource : `./${relativeSource}`\n}\n\nfunction buildCssImports(source: string, theme: ThemeOption, cssPath: string) {\n const imports = []\n const hasTailwind = /@import\\s+['\"]tailwindcss['\"]/.test(source)\n const hasTheme = /@import\\s+['\"]@uselets\\/ui\\/themes\\/(?:max|gomax)\\.css['\"]/.test(source)\n const hasFont = /@import\\s+['\"]@fontsource-variable\\/inter['\"]/.test(source)\n const hasPackageSource = /@source\\s+['\"][^'\"]*@uselets\\/ui\\/dist['\"]/.test(source)\n\n if (!hasTailwind) {\n imports.push(\"@import 'tailwindcss';\")\n }\n\n if (!hasTheme) {\n imports.push(`@import '@uselets/ui/themes/${theme}.css';`)\n }\n\n if (!hasFont) {\n imports.push(\"@import '@fontsource-variable/inter';\")\n }\n\n if (!hasPackageSource) {\n imports.push(`@source '${buildPackageSource(cssPath)}';`)\n }\n\n return { imports, hasTheme }\n}\n\nasync function ensureGlobalCss(projectRoot: string, cssPath: string, theme: ThemeOption) {\n const absoluteCssPath = path.resolve(projectRoot, cssPath)\n const existingSource = (await pathExists(absoluteCssPath)) ? await fs.readFile(absoluteCssPath, 'utf8') : ''\n const { imports, hasTheme } = buildCssImports(existingSource, theme, cssPath)\n\n if (hasTheme) {\n console.log('Preserved existing @uselets/ui theme import.')\n }\n\n if (imports.length === 0) {\n console.log(`Global CSS already configured at ${cssPath}.`)\n return\n }\n\n const separator = existingSource.length > 0 && !existingSource.startsWith('\\n') ? '\\n' : ''\n const updatedSource = `${imports.join('\\n')}${separator}${existingSource}`\n\n await fs.mkdir(path.dirname(absoluteCssPath), { recursive: true })\n await fs.writeFile(absoluteCssPath, updatedSource)\n console.log(`Updated global CSS at ${cssPath}.`)\n}\n\nasync function initProject(options: InitOptions) {\n const projectRoot = process.cwd()\n const packageJsonPath = path.join(projectRoot, 'package.json')\n\n if (!(await pathExists(packageJsonPath))) {\n throw new Error('No package.json found in the current directory. Run uselets init from your project root.')\n }\n\n const projectPackageJson = await readJsonFile<PackageJson>(packageJsonPath)\n const theme = options.theme ?? (await promptTheme('max'))\n const cssPath = options.css ?? (await promptCssPath(DEFAULT_CSS_PATH))\n const shouldInstallSkill = options.installSkill ?? (await promptInstallSkill())\n\n await installMissingDependencies(projectRoot, projectPackageJson)\n await ensurePostcssConfig(projectRoot)\n await ensureGlobalCss(projectRoot, cssPath, theme)\n\n if (shouldInstallSkill) {\n await installSkill(ALL_AGENT_TARGETS)\n }\n}\n\nasync function main() {\n const program = new Command()\n\n program.name('uselets').description('CLI for @uselets/ui').showHelpAfterError()\n\n program\n .command('skill')\n .description(`Reinstall the ${SKILL_NAME} agent skill`)\n .addOption(\n new Option('--agent <agent>', 'Target agent directory').choices(['codex', 'claude', 'all']).default('all')\n )\n .action(async (options: { agent: AgentOption }) => {\n await installSkill(resolveTargets(options.agent))\n })\n\n program\n .command('init')\n .description('Set up @uselets/ui in this project')\n .addOption(new Option('--theme <theme>', 'Theme to import').choices(['max', 'gomax']))\n .option('--css <path>', 'Global CSS file path')\n .option('--install-skill', 'Install the agent skill without prompting')\n .option('--no-install-skill', 'Skip the agent skill prompt and installation')\n .action(async (options: InitOptions) => {\n await initProject(options)\n })\n\n if (process.argv.length <= 2) {\n program.outputHelp()\n return\n }\n\n await program.parseAsync()\n}\n\nmain().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : error)\n process.exitCode = 1\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"uselets.mjs","names":[],"sources":["../../src/cli/uselets.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { spawn } from 'node:child_process'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport readline from 'node:readline/promises'\nimport { fileURLToPath } from 'node:url'\n\nimport { Command, Option } from 'commander'\n\nconst SKILL_NAME = 'uselets-ui'\nconst DEFAULT_CSS_PATH = 'src/styles/globals.css'\nconst FONT_PACKAGE = '@fontsource-variable/inter'\nconst ENTRY_FILE_CANDIDATES = [\n 'app/layout.tsx',\n 'app/layout.jsx',\n 'pages/_app.tsx',\n 'pages/_app.jsx',\n 'src/main.tsx',\n 'src/main.jsx',\n 'src/index.tsx',\n 'src/index.jsx'\n]\nconst POSTCSS_CONFIG = \"export { default } from '@uselets/ui/postcss.config'\\n\"\nconst AGENT_TARGETS = {\n codex: path.join('.agents', 'skills', SKILL_NAME),\n claude: path.join('.claude', 'skills', SKILL_NAME)\n} as const\n\ntype AgentTarget = keyof typeof AGENT_TARGETS\ntype AgentOption = AgentTarget | 'all'\ntype ThemeOption = 'max' | 'gomax'\ntype PackageManager = 'bun' | 'pnpm' | 'yarn' | 'npm'\ntype PackageJson = {\n name?: string\n version?: string\n packageManager?: string\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n optionalDependencies?: Record<string, string>\n}\ntype InitOptions = {\n theme?: ThemeOption\n css?: string\n entry?: string\n installSkill?: boolean\n}\n\nconst ALL_AGENT_TARGETS = Object.keys(AGENT_TARGETS) as AgentTarget[]\n\nasync function pathExists(targetPath: string) {\n try {\n await fs.access(targetPath)\n return true\n } catch {\n return false\n }\n}\n\nasync function readJsonFile<T>(filePath: string) {\n return JSON.parse(await fs.readFile(filePath, 'utf8')) as T\n}\n\nasync function findPackageRoot() {\n let currentDir = fileURLToPath(new URL('.', import.meta.url))\n\n while (true) {\n try {\n await fs.access(path.join(currentDir, 'package.json'))\n return currentDir\n } catch {\n const parentDir = path.dirname(currentDir)\n\n if (parentDir === currentDir) {\n throw new Error('Unable to resolve @uselets/ui package root')\n }\n\n currentDir = parentDir\n }\n }\n}\n\nfunction resolveTargets(agent: AgentOption) {\n return agent === 'all' ? ALL_AGENT_TARGETS : [agent]\n}\n\nfunction hasDependency(packageJson: PackageJson, dependencyName: string) {\n return Boolean(\n packageJson.dependencies?.[dependencyName] ||\n packageJson.devDependencies?.[dependencyName] ||\n packageJson.peerDependencies?.[dependencyName] ||\n packageJson.optionalDependencies?.[dependencyName]\n )\n}\n\nasync function detectPackageManager(projectRoot: string, packageJson: PackageJson): Promise<PackageManager> {\n const declaredManager = packageJson.packageManager?.split('@')[0]\n\n if (\n declaredManager === 'bun' ||\n declaredManager === 'pnpm' ||\n declaredManager === 'yarn' ||\n declaredManager === 'npm'\n ) {\n return declaredManager\n }\n\n if (await pathExists(path.join(projectRoot, 'bun.lock'))) {\n return 'bun'\n }\n\n if (await pathExists(path.join(projectRoot, 'pnpm-lock.yaml'))) {\n return 'pnpm'\n }\n\n if (await pathExists(path.join(projectRoot, 'yarn.lock'))) {\n return 'yarn'\n }\n\n if (await pathExists(path.join(projectRoot, 'package-lock.json'))) {\n return 'npm'\n }\n\n return 'npm'\n}\n\nfunction buildAddCommand(packageManager: PackageManager, dependencies: string[], dev: boolean) {\n switch (packageManager) {\n case 'bun':\n return ['bun', 'add', ...(dev ? ['-d'] : []), ...dependencies]\n case 'pnpm':\n return ['pnpm', 'add', ...(dev ? ['-D'] : []), ...dependencies]\n case 'yarn':\n return ['yarn', 'add', ...(dev ? ['-D'] : []), ...dependencies]\n case 'npm':\n return ['npm', 'install', ...(dev ? ['-D'] : []), ...dependencies]\n }\n}\n\nasync function runCommand(commandParts: string[], cwd: string) {\n const [command, ...args] = commandParts\n\n if (!command) {\n throw new Error('Missing command')\n }\n\n console.log(`Running: ${commandParts.join(' ')}`)\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command, args, { cwd, stdio: 'inherit' })\n\n child.on('error', reject)\n child.on('close', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n\n reject(new Error(`${command} exited with code ${code}`))\n })\n })\n}\n\nfunction getPackageVersion(packageJson: PackageJson, dependencyName: string) {\n const version = packageJson.dependencies?.[dependencyName] ?? packageJson.devDependencies?.[dependencyName]\n\n if (!version) {\n throw new Error(`Unable to find ${dependencyName} version in @uselets/ui package metadata`)\n }\n\n return version\n}\n\nasync function installMissingDependencies(projectRoot: string, projectPackageJson: PackageJson) {\n const packageRoot = await findPackageRoot()\n const packageJson = await readJsonFile<PackageJson>(path.join(packageRoot, 'package.json'))\n const packageManager = await detectPackageManager(projectRoot, projectPackageJson)\n const runtimeDependencies = []\n const devDependencies = []\n\n if (!packageJson.name || !packageJson.version) {\n throw new Error('Unable to resolve @uselets/ui package name and version')\n }\n\n if (!hasDependency(projectPackageJson, packageJson.name)) {\n runtimeDependencies.push(`${packageJson.name}@${packageJson.version}`)\n }\n\n if (!hasDependency(projectPackageJson, FONT_PACKAGE)) {\n runtimeDependencies.push(`${FONT_PACKAGE}@${getPackageVersion(packageJson, FONT_PACKAGE)}`)\n }\n\n if (!hasDependency(projectPackageJson, 'tailwindcss')) {\n devDependencies.push(`tailwindcss@${getPackageVersion(packageJson, 'tailwindcss')}`)\n }\n\n if (!hasDependency(projectPackageJson, '@tailwindcss/postcss')) {\n devDependencies.push(`@tailwindcss/postcss@${getPackageVersion(packageJson, '@tailwindcss/postcss')}`)\n }\n\n if (runtimeDependencies.length > 0) {\n await runCommand(buildAddCommand(packageManager, runtimeDependencies, false), projectRoot)\n } else {\n console.log('Runtime dependencies already declared.')\n }\n\n if (devDependencies.length > 0) {\n await runCommand(buildAddCommand(packageManager, devDependencies, true), projectRoot)\n } else {\n console.log('Tailwind dependencies already declared.')\n }\n}\n\nasync function installSkill(targets: AgentTarget[]) {\n const packageRoot = await findPackageRoot()\n const sourcePath = path.join(packageRoot, 'skills', SKILL_NAME)\n\n try {\n await fs.access(sourcePath)\n } catch {\n throw new Error(`Bundled skill not found at ${sourcePath}`)\n }\n\n const installedPaths = []\n\n for (const target of targets) {\n const targetPath = path.join(process.cwd(), AGENT_TARGETS[target])\n\n await fs.rm(targetPath, { recursive: true, force: true })\n await fs.mkdir(path.dirname(targetPath), { recursive: true })\n await fs.cp(sourcePath, targetPath, { recursive: true })\n\n installedPaths.push(targetPath)\n }\n\n console.log(`Installed ${SKILL_NAME} skill:`)\n\n for (const installedPath of installedPaths) {\n console.log(`- ${installedPath}`)\n }\n}\n\nasync function createPrompt() {\n return readline.createInterface({ input: process.stdin, output: process.stdout })\n}\n\nasync function promptTheme(defaultTheme: ThemeOption) {\n if (!process.stdin.isTTY) {\n return defaultTheme\n }\n\n const prompt = await createPrompt()\n\n try {\n while (true) {\n const answer = (await prompt.question(`Theme (max/gomax) [${defaultTheme}]: `)).trim().toLowerCase()\n\n if (!answer) {\n return defaultTheme\n }\n\n if (answer === 'max' || answer === 'gomax') {\n return answer\n }\n\n console.log('Please choose \"max\" or \"gomax\".')\n }\n } finally {\n prompt.close()\n }\n}\n\nasync function promptCssPath(defaultCssPath: string) {\n if (!process.stdin.isTTY) {\n return defaultCssPath\n }\n\n const prompt = await createPrompt()\n\n try {\n const answer = (await prompt.question(`Global CSS path [${defaultCssPath}]: `)).trim()\n return answer || defaultCssPath\n } finally {\n prompt.close()\n }\n}\n\nasync function promptInstallSkill() {\n if (!process.stdin.isTTY) {\n return false\n }\n\n const prompt = await createPrompt()\n\n try {\n while (true) {\n const answer = (await prompt.question('Install agent skill? (y/N): ')).trim().toLowerCase()\n\n if (!answer || answer === 'n' || answer === 'no') {\n return false\n }\n\n if (answer === 'y' || answer === 'yes') {\n return true\n }\n\n console.log('Please answer \"y\" or \"n\".')\n }\n } finally {\n prompt.close()\n }\n}\n\nasync function ensurePostcssConfig(projectRoot: string) {\n const postcssPath = path.join(projectRoot, 'postcss.config.mjs')\n\n if (await pathExists(postcssPath)) {\n console.log('Preserved existing postcss.config.mjs.')\n return\n }\n\n await fs.writeFile(postcssPath, POSTCSS_CONFIG)\n console.log('Created postcss.config.mjs.')\n}\n\nfunction buildPackageSource(cssPath: string) {\n const cssDir = path.posix.dirname(cssPath.replaceAll(path.sep, path.posix.sep))\n const relativeSource = path.posix.relative(cssDir, 'node_modules/@uselets/ui/dist')\n\n return relativeSource.startsWith('.') ? relativeSource : `./${relativeSource}`\n}\n\nfunction buildCssImports(source: string, theme: ThemeOption, cssPath: string) {\n const imports = []\n const hasTailwind = /@import\\s+['\"]tailwindcss['\"]/.test(source)\n const hasTheme = /@import\\s+['\"]@uselets\\/ui\\/themes\\/(?:max|gomax)\\.css['\"]/.test(source)\n const hasPackageSource = /@source\\s+['\"][^'\"]*@uselets\\/ui\\/dist['\"]/.test(source)\n\n if (!hasTailwind) {\n imports.push(\"@import 'tailwindcss';\")\n }\n\n if (!hasTheme) {\n imports.push(`@import '@uselets/ui/themes/${theme}.css';`)\n }\n\n if (!hasPackageSource) {\n imports.push(`@source '${buildPackageSource(cssPath)}';`)\n }\n\n return { imports, hasTheme }\n}\n\nasync function ensureGlobalCss(projectRoot: string, cssPath: string, theme: ThemeOption) {\n const absoluteCssPath = path.resolve(projectRoot, cssPath)\n const existingSource = (await pathExists(absoluteCssPath)) ? await fs.readFile(absoluteCssPath, 'utf8') : ''\n const { imports, hasTheme } = buildCssImports(existingSource, theme, cssPath)\n\n if (hasTheme) {\n console.log('Preserved existing @uselets/ui theme import.')\n }\n\n if (imports.length === 0) {\n console.log(`Global CSS already configured at ${cssPath}.`)\n return\n }\n\n const separator = existingSource.length > 0 && !existingSource.startsWith('\\n') ? '\\n' : ''\n const updatedSource = `${imports.join('\\n')}${separator}${existingSource}`\n\n await fs.mkdir(path.dirname(absoluteCssPath), { recursive: true })\n await fs.writeFile(absoluteCssPath, updatedSource)\n console.log(`Updated global CSS at ${cssPath}.`)\n}\n\nasync function detectEntryFile(projectRoot: string) {\n for (const candidate of ENTRY_FILE_CANDIDATES) {\n if (await pathExists(path.join(projectRoot, candidate))) {\n return candidate\n }\n }\n\n return undefined\n}\n\nasync function promptEntryPath() {\n if (!process.stdin.isTTY) {\n return undefined\n }\n\n const prompt = await createPrompt()\n\n try {\n const answer = (await prompt.question('App entry file to import the font in (leave empty to skip): ')).trim()\n return answer || undefined\n } finally {\n prompt.close()\n }\n}\n\nasync function resolveEntryPath(projectRoot: string, entryOption?: string) {\n if (entryOption) {\n return entryOption\n }\n\n const detected = await detectEntryFile(projectRoot)\n\n if (detected) {\n return detected\n }\n\n return promptEntryPath()\n}\n\nfunction logManualFontImportInstructions(reason: string) {\n console.log(\n `${reason} Add \\`import '${FONT_PACKAGE}'\\` to your app's entry file (for example app/layout.tsx or src/main.tsx) to load the font.`\n )\n}\n\nasync function ensureFontImport(projectRoot: string, entryPath?: string) {\n if (!entryPath) {\n logManualFontImportInstructions('Could not detect an app entry file.')\n return\n }\n\n const absoluteEntryPath = path.resolve(projectRoot, entryPath)\n\n if (!(await pathExists(absoluteEntryPath))) {\n logManualFontImportInstructions(`Entry file ${entryPath} not found.`)\n return\n }\n\n const source = await fs.readFile(absoluteEntryPath, 'utf8')\n const importPattern = new RegExp(`import\\\\s+['\"]${FONT_PACKAGE}['\"]`)\n\n if (importPattern.test(source)) {\n console.log(`Font import already present in ${entryPath}.`)\n return\n }\n\n const directiveMatch = source.match(/^(['\"])use (?:client|server)\\1;?\\r?\\n/)\n const insertion = `import '${FONT_PACKAGE}'\\n`\n const updatedSource = directiveMatch\n ? source.slice(0, directiveMatch[0].length) + insertion + source.slice(directiveMatch[0].length)\n : insertion + source\n\n await fs.writeFile(absoluteEntryPath, updatedSource)\n console.log(`Added font import to ${entryPath}.`)\n}\n\nasync function initProject(options: InitOptions) {\n const projectRoot = process.cwd()\n const packageJsonPath = path.join(projectRoot, 'package.json')\n\n if (!(await pathExists(packageJsonPath))) {\n throw new Error('No package.json found in the current directory. Run uselets init from your project root.')\n }\n\n const projectPackageJson = await readJsonFile<PackageJson>(packageJsonPath)\n const theme = options.theme ?? (await promptTheme('max'))\n const cssPath = options.css ?? (await promptCssPath(DEFAULT_CSS_PATH))\n const entryPath = await resolveEntryPath(projectRoot, options.entry)\n const shouldInstallSkill = options.installSkill ?? (await promptInstallSkill())\n\n await installMissingDependencies(projectRoot, projectPackageJson)\n await ensurePostcssConfig(projectRoot)\n await ensureGlobalCss(projectRoot, cssPath, theme)\n await ensureFontImport(projectRoot, entryPath)\n\n if (shouldInstallSkill) {\n await installSkill(ALL_AGENT_TARGETS)\n }\n}\n\nasync function main() {\n const program = new Command()\n\n program.name('uselets').description('CLI for @uselets/ui').showHelpAfterError()\n\n program\n .command('skill')\n .description(`Reinstall the ${SKILL_NAME} agent skill`)\n .addOption(\n new Option('--agent <agent>', 'Target agent directory').choices(['codex', 'claude', 'all']).default('all')\n )\n .action(async (options: { agent: AgentOption }) => {\n await installSkill(resolveTargets(options.agent))\n })\n\n program\n .command('init')\n .description('Set up @uselets/ui in this project')\n .addOption(new Option('--theme <theme>', 'Theme to import').choices(['max', 'gomax']))\n .option('--css <path>', 'Global CSS file path')\n .option('--entry <path>', 'App entry file to import the font in (for example app/layout.tsx or src/main.tsx)')\n .option('--install-skill', 'Install the agent skill without prompting')\n .option('--no-install-skill', 'Skip the agent skill prompt and installation')\n .action(async (options: InitOptions) => {\n await initProject(options)\n })\n\n if (process.argv.length <= 2) {\n program.outputHelp()\n return\n }\n\n await program.parseAsync()\n}\n\nmain().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : error)\n process.exitCode = 1\n})\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../rolldown-runtime-Bdj-bS2b.js";import{cn as e}from"../lib/utils.js";import{useFieldControlId as t}from"./field.js";import{Slider as n}from"radix-ui";import{jsx as r,jsxs as i}from"react/jsx-runtime";import*as a from"react";function Slider({className:o,defaultValue:s,id:c,value:l,min:u=0,max:d=100,...f}){let p=t(c),m=a.useMemo(()=>Array.isArray(l)?l:Array.isArray(s)?s:[u,d],[l,s,u,d]);return i(n.Root,{id:p,"data-slot":`slider`,defaultValue:s,value:l,min:u,max:d,className:e(`relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col`,o),...f,children:[r(n.Track,{"data-slot":`slider-track`,className:e(`relative grow overflow-hidden rounded-full bg-muted`,`data-horizontal:h-1 data-horizontal:w-full`,`data-vertical:h-full data-vertical:w-1`),children:r(n.Range,{"data-slot":`slider-range`,className:`absolute bg-primary select-none data-horizontal:h-full data-vertical:w-full`})}),m.map(t=>r(n.Thumb,{"data-slot":`slider-thumb`,className:e(`relative block size-3 shrink-0 rounded-full border border-ring bg-white ring-ring/50`,`transition-[color,box-shadow] select-none after:absolute after:-inset-2`,`hover:ring-3 focus-visible:ring-3 focus-visible:outline-hidden active:ring-3`,`disabled:pointer-events-none disabled:opacity-50`)},
|
|
1
|
+
import"../rolldown-runtime-Bdj-bS2b.js";import{cn as e}from"../lib/utils.js";import{useFieldControlId as t}from"./field.js";import{Slider as n}from"radix-ui";import{jsx as r,jsxs as i}from"react/jsx-runtime";import*as a from"react";function Slider({className:o,defaultValue:s,id:c,value:l,min:u=0,max:d=100,...f}){let p=t(c),m=a.useMemo(()=>Array.isArray(l)?l:Array.isArray(s)?s:[u,d],[l,s,u,d]);return i(n.Root,{id:p,"data-slot":`slider`,defaultValue:s,value:l,min:u,max:d,className:e(`relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col`,o),...f,children:[r(n.Track,{"data-slot":`slider-track`,className:e(`relative grow overflow-hidden rounded-full bg-muted`,`data-horizontal:h-1 data-horizontal:w-full`,`data-vertical:h-full data-vertical:w-1`),children:r(n.Range,{"data-slot":`slider-range`,className:`absolute bg-primary select-none data-horizontal:h-full data-vertical:w-full`})}),m.map((t,i)=>r(n.Thumb,{"data-slot":`slider-thumb`,className:e(`relative block size-3 shrink-0 rounded-full border border-ring bg-white dark:bg-primary ring-ring/50`,`transition-[color,box-shadow] select-none after:absolute after:-inset-2`,`hover:ring-3 focus-visible:ring-3 focus-visible:outline-hidden active:ring-3`,`disabled:pointer-events-none disabled:opacity-50`)},String(i)))]})}export{Slider};
|
|
2
2
|
//# sourceMappingURL=slider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slider.js","names":["SliderPrimitive"],"sources":["../../src/components/slider.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport { Slider as SliderPrimitive } from 'radix-ui'\n\nimport { cn } from '../lib/utils'\nimport { useFieldControlId } from './field'\n\nexport type SliderProps = React.ComponentProps<typeof SliderPrimitive.Root>\n\nfunction Slider({ className, defaultValue, id, value, min = 0, max = 100, ...props }: SliderProps) {\n const fieldControlId = useFieldControlId(id)\n const
|
|
1
|
+
{"version":3,"file":"slider.js","names":["SliderPrimitive"],"sources":["../../src/components/slider.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport { Slider as SliderPrimitive } from 'radix-ui'\n\nimport { cn } from '../lib/utils'\nimport { useFieldControlId } from './field'\n\nexport type SliderProps = React.ComponentProps<typeof SliderPrimitive.Root>\n\nfunction Slider({ className, defaultValue, id, value, min = 0, max = 100, ...props }: SliderProps) {\n const fieldControlId = useFieldControlId(id)\n const values = React.useMemo(\n () => (Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max]),\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n id={fieldControlId}\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n className={cn(\n 'relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col',\n className\n )}\n {...props}\n >\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className={cn(\n 'relative grow overflow-hidden rounded-full bg-muted',\n 'data-horizontal:h-1 data-horizontal:w-full',\n 'data-vertical:h-full data-vertical:w-1'\n )}\n >\n <SliderPrimitive.Range\n data-slot=\"slider-range\"\n className=\"absolute bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {values.map((_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={String(index)}\n className={cn(\n 'relative block size-3 shrink-0 rounded-full border border-ring bg-white dark:bg-primary ring-ring/50',\n 'transition-[color,box-shadow] select-none after:absolute after:-inset-2',\n 'hover:ring-3 focus-visible:ring-3 focus-visible:outline-hidden active:ring-3',\n 'disabled:pointer-events-none disabled:opacity-50'\n )}\n />\n ))}\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n"],"mappings":"wOASA,SAAS,OAAO,CAAE,YAAW,eAAc,KAAI,QAAO,MAAM,EAAG,MAAM,IAAK,GAAG,GAAsB,CACjG,IAAM,EAAiB,EAAkB,CAAE,EACrC,EAAS,EAAM,YACZ,MAAM,QAAQ,CAAK,EAAI,EAAQ,MAAM,QAAQ,CAAY,EAAI,EAAe,CAAC,EAAK,CAAG,EAC5F,CAAC,EAAO,EAAc,EAAK,CAAG,CAChC,EAEA,OACE,EAACA,EAAgB,KAAjB,CACE,GAAI,EACJ,YAAU,SACI,eACP,QACF,MACA,MACL,UAAW,EACT,4KACA,CACF,EACA,GAAI,EAXN,SAAA,CAaE,EAACA,EAAgB,MAAjB,CACE,YAAU,eACV,UAAW,EACT,sDACA,6CACA,wCACF,EAEA,SAAA,EAACA,EAAgB,MAAjB,CACE,YAAU,eACV,UAAU,6EACX,CAAA,CACoB,CAAA,EACtB,EAAO,KAAK,EAAG,IACd,EAACA,EAAgB,MAAjB,CACE,YAAU,eAEV,UAAW,EACT,uGACA,0EACA,+EACA,kDACF,CACD,EAPM,OAAO,CAAK,CAOlB,CACF,CACmB,GAE1B"}
|
|
@@ -7,13 +7,14 @@ type ThemeProviderProps = {
|
|
|
7
7
|
children: React.ReactNode;
|
|
8
8
|
defaultTheme?: Theme;
|
|
9
9
|
storageKey?: string;
|
|
10
|
+
disableTransitionOnChange?: boolean;
|
|
10
11
|
};
|
|
11
12
|
type ThemeProviderState = {
|
|
12
13
|
theme: Theme;
|
|
13
14
|
setTheme: (theme: Theme) => void;
|
|
14
15
|
};
|
|
15
16
|
type ModeToggleProps = React.ComponentProps<typeof Button>;
|
|
16
|
-
declare function ThemeProvider({ children, defaultTheme, storageKey, ...props }: ThemeProviderProps): React.JSX.Element;
|
|
17
|
+
declare function ThemeProvider({ children, defaultTheme, storageKey, disableTransitionOnChange, ...props }: ThemeProviderProps): React.JSX.Element;
|
|
17
18
|
declare const useTheme: () => ThemeProviderState;
|
|
18
19
|
declare function ModeToggle(props: ModeToggleProps): React.JSX.Element;
|
|
19
20
|
//#endregion
|
package/dist/components/theme.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../rolldown-runtime-Bdj-bS2b.js";import{Button as e}from"./button.js";import{DropdownMenu as t,DropdownMenuContent as n,DropdownMenuItem as r,DropdownMenuTrigger as i}from"./dropdown-menu.js";import{IconMoon as a,IconSun as o}from"@tabler/icons-react";import{jsx as s,jsxs as c}from"react/jsx-runtime";import{createContext as l,use as u,useEffect as d,useState as f}from"react";const p=l({});function ThemeProvider({children:e,defaultTheme:t=`system`,storageKey:n=`vite-ui-theme
|
|
1
|
+
import"../rolldown-runtime-Bdj-bS2b.js";import{Button as e}from"./button.js";import{DropdownMenu as t,DropdownMenuContent as n,DropdownMenuItem as r,DropdownMenuTrigger as i}from"./dropdown-menu.js";import{IconMoon as a,IconSun as o}from"@tabler/icons-react";import{jsx as s,jsxs as c}from"react/jsx-runtime";import{createContext as l,use as u,useEffect as d,useState as f}from"react";const p=l({});function disableAnimation(){let e=document.createElement(`style`);return e.appendChild(document.createTextNode(`*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`)),document.head.appendChild(e),()=>{window.getComputedStyle(document.body),setTimeout(()=>{document.head.removeChild(e)},1)}}function ThemeProvider({children:e,defaultTheme:t=`system`,storageKey:n=`vite-ui-theme`,disableTransitionOnChange:r=!1,...i}){let[a,o]=f(()=>localStorage.getItem(n)||t);d(()=>{let e=window.document.documentElement,t=r?disableAnimation():null;e.classList.remove(`light`,`dark`);let n=a===`system`?window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`:a;e.classList.add(n),t?.()},[a,r]);let c={theme:a,setTheme:e=>{localStorage.setItem(n,e),o(e)}};return s(p.Provider,{...i,value:c,children:e})}const useTheme=()=>{let e=u(p);if(e===void 0||Object.keys(e).length===0)throw Error(`useTheme must be used within a ThemeProvider`);return e};function ModeToggle(l){let{setTheme:u}=useTheme();return c(t,{children:[s(i,{asChild:!0,children:c(e,{variant:`outline`,size:`icon`,...l,children:[s(o,{className:`h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90`}),s(a,{className:`absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0`}),s(`span`,{className:`sr-only`,children:`Toggle theme`})]})}),c(n,{align:`end`,children:[s(r,{onClick:()=>u(`light`),children:`Light`}),s(r,{onClick:()=>u(`dark`),children:`Dark`}),s(r,{onClick:()=>u(`system`),children:`System`})]})]})}export{ModeToggle,ThemeProvider,useTheme};
|
|
2
2
|
//# sourceMappingURL=theme.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.js","names":[],"sources":["../../src/components/theme.tsx"],"sourcesContent":["import type * as React from 'react'\nimport { createContext, use, useEffect, useState } from 'react'\n\nimport { IconMoon, IconSun } from '@tabler/icons-react'\n\nimport { Button } from './button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from './dropdown-menu'\n\nexport type Theme = 'dark' | 'light' | 'system'\n\nexport type ThemeProviderProps = {\n children: React.ReactNode\n defaultTheme?: Theme\n storageKey?: string\n}\n\nexport type ThemeProviderState = {\n theme: Theme\n setTheme: (theme: Theme) => void\n}\n\nexport type ModeToggleProps = React.ComponentProps<typeof Button>\n\nconst ThemeProviderContext = createContext({} as ThemeProviderState)\n\nexport function ThemeProvider({\n children,\n defaultTheme = 'system',\n storageKey = 'vite-ui-theme',\n ...props\n}: ThemeProviderProps) {\n const [theme, setTheme] = useState<Theme>(() => (localStorage.getItem(storageKey) as Theme) || defaultTheme)\n\n useEffect(() => {\n const root = window.document.documentElement\n\n root.classList.remove('light', 'dark')\n\n
|
|
1
|
+
{"version":3,"file":"theme.js","names":[],"sources":["../../src/components/theme.tsx"],"sourcesContent":["import type * as React from 'react'\nimport { createContext, use, useEffect, useState } from 'react'\n\nimport { IconMoon, IconSun } from '@tabler/icons-react'\n\nimport { Button } from './button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from './dropdown-menu'\n\nexport type Theme = 'dark' | 'light' | 'system'\n\nexport type ThemeProviderProps = {\n children: React.ReactNode\n defaultTheme?: Theme\n storageKey?: string\n disableTransitionOnChange?: boolean\n}\n\nexport type ThemeProviderState = {\n theme: Theme\n setTheme: (theme: Theme) => void\n}\n\nexport type ModeToggleProps = React.ComponentProps<typeof Button>\n\nconst ThemeProviderContext = createContext({} as ThemeProviderState)\n\nfunction disableAnimation() {\n const css = document.createElement('style')\n\n css.appendChild(\n document.createTextNode(\n '*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}'\n )\n )\n document.head.appendChild(css)\n\n return () => {\n window.getComputedStyle(document.body)\n\n setTimeout(() => {\n document.head.removeChild(css)\n }, 1)\n }\n}\n\nexport function ThemeProvider({\n children,\n defaultTheme = 'system',\n storageKey = 'vite-ui-theme',\n disableTransitionOnChange = false,\n ...props\n}: ThemeProviderProps) {\n const [theme, setTheme] = useState<Theme>(() => (localStorage.getItem(storageKey) as Theme) || defaultTheme)\n\n useEffect(() => {\n const root = window.document.documentElement\n const enableTransitions = disableTransitionOnChange ? disableAnimation() : null\n\n root.classList.remove('light', 'dark')\n\n const resolvedTheme =\n theme === 'system' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme\n\n root.classList.add(resolvedTheme)\n\n enableTransitions?.()\n }, [theme, disableTransitionOnChange])\n\n const value = {\n theme,\n setTheme: (theme: Theme) => {\n localStorage.setItem(storageKey, theme)\n setTheme(theme)\n }\n }\n\n return (\n <ThemeProviderContext.Provider {...props} value={value}>\n {children}\n </ThemeProviderContext.Provider>\n )\n}\n\nexport const useTheme = () => {\n const context = use(ThemeProviderContext)\n\n if (context === undefined || Object.keys(context).length === 0) {\n throw new Error('useTheme must be used within a ThemeProvider')\n }\n\n return context\n}\n\nexport function ModeToggle(props: ModeToggleProps) {\n const { setTheme } = useTheme()\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"icon\" {...props}>\n <IconSun className=\"h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90\" />\n <IconMoon className=\"absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0\" />\n <span className=\"sr-only\">Toggle theme</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setTheme('light')}>Light</DropdownMenuItem>\n <DropdownMenuItem onClick={() => setTheme('dark')}>Dark</DropdownMenuItem>\n <DropdownMenuItem onClick={() => setTheme('system')}>System</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n"],"mappings":"iYAwBA,MAAM,EAAuB,EAAc,CAAC,CAAuB,EAEnE,SAAS,kBAAmB,CAC1B,IAAM,EAAM,SAAS,cAAc,OAAO,EAS1C,OAPA,EAAI,YACF,SAAS,eACP,6KACF,CACF,EACA,SAAS,KAAK,YAAY,CAAG,MAEhB,CACX,OAAO,iBAAiB,SAAS,IAAI,EAErC,eAAiB,CACf,SAAS,KAAK,YAAY,CAAG,CAC/B,EAAG,CAAC,CACN,CACF,CAEA,SAAgB,cAAc,CAC5B,WACA,eAAe,SACf,aAAa,gBACb,4BAA4B,GAC5B,GAAG,GACkB,CACrB,GAAM,CAAC,EAAO,GAAY,MAAuB,aAAa,QAAQ,CAAU,GAAe,CAAY,EAE3G,MAAgB,CACd,IAAM,EAAO,OAAO,SAAS,gBACvB,EAAoB,EAA4B,iBAAiB,EAAI,KAE3E,EAAK,UAAU,OAAO,QAAS,MAAM,EAErC,IAAM,EACJ,IAAU,SAAY,OAAO,WAAW,8BAA8B,CAAC,CAAC,QAAU,OAAS,QAAW,EAExG,EAAK,UAAU,IAAI,CAAa,EAEhC,IAAoB,CACtB,EAAG,CAAC,EAAO,CAAyB,CAAC,EAErC,IAAM,EAAQ,CACZ,QACA,SAAW,GAAiB,CAC1B,aAAa,QAAQ,EAAY,CAAK,EACtC,EAAS,CAAK,CAChB,CACF,EAEA,OACE,EAAC,EAAqB,SAAtB,CAA+B,GAAI,EAAc,QAC9C,UAC4B,CAAA,CAEnC,CAEA,MAAa,aAAiB,CAC5B,IAAM,EAAU,EAAI,CAAoB,EAExC,GAAI,IAAY,IAAA,IAAa,OAAO,KAAK,CAAO,CAAC,CAAC,SAAW,EAC3D,MAAU,MAAM,8CAA8C,EAGhE,OAAO,CACT,EAEA,SAAgB,WAAW,EAAwB,CACjD,GAAM,CAAE,YAAa,SAAS,EAE9B,OACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAqB,QAAA,GACnB,SAAA,EAAC,EAAD,CAAQ,QAAQ,UAAU,KAAK,OAAO,GAAI,EAA1C,SAAA,CACE,EAAC,EAAD,CAAS,UAAU,sFAAwF,CAAA,EAC3G,EAAC,EAAD,CAAU,UAAU,8FAAgG,CAAA,EACpH,EAAC,OAAD,CAAM,UAAU,UAAU,SAAA,cAAkB,CAAA,CACtC,GACW,CAAA,EACrB,EAAC,EAAD,CAAqB,MAAM,MAA3B,SAAA,CACE,EAAC,EAAD,CAAkB,YAAe,EAAS,OAAO,EAAG,SAAA,OAAuB,CAAA,EAC3E,EAAC,EAAD,CAAkB,YAAe,EAAS,MAAM,EAAG,SAAA,MAAsB,CAAA,EACzE,EAAC,EAAD,CAAkB,YAAe,EAAS,QAAQ,EAAG,SAAA,QAAwB,CAAA,CAC1D,CACT,CAAA,CAAA,CAAA,CAAA,CAElB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../rolldown-runtime-Bdj-bS2b.js";import{cn as e}from"../lib/utils.js";import{toggleVariants as t}from"./toggle.js";import{ToggleGroup as n}from"radix-ui";import{jsx as r}from"react/jsx-runtime";import*as i from"react";const a=i.createContext({size:`md`,variant:`ghost`,color:`primary`,spacing:0,orientation:`horizontal`});function ToggleGroup({className:t,variant:i,color:o,size:s,spacing:c=0,orientation:l=`horizontal`,children:u,...d}){return r(n.Root,{"data-slot":`toggle-group`,"data-variant":i??`ghost`,"data-color":o??`primary`,"data-size":s??`md`,"data-spacing":c,"data-orientation":l,style:{"--gap":c},className:e(`group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch`,t),...d,children:r(a.Provider,{value:{variant:i,color:o,size:s,spacing:c,orientation:l},children:u})})}function ToggleGroupItem({className:o,children:s,variant:c=`ghost`,color:l=`primary`,size:u=`md`,...d}){let f=i.useContext(a);return r(n.Item,{"data-slot":`toggle-group-item`,"data-variant":f.variant||c,"data-color":f.color||l,"data-size":f.size||u,"data-spacing":f.spacing,className:e(`shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg
|
|
1
|
+
import"../rolldown-runtime-Bdj-bS2b.js";import{cn as e}from"../lib/utils.js";import{toggleVariants as t}from"./toggle.js";import{ToggleGroup as n}from"radix-ui";import{jsx as r}from"react/jsx-runtime";import*as i from"react";const a=i.createContext({size:`md`,variant:`ghost`,color:`primary`,spacing:0,orientation:`horizontal`});function ToggleGroup({className:t,variant:i,color:o,size:s,spacing:c=0,orientation:l=`horizontal`,children:u,...d}){return r(n.Root,{"data-slot":`toggle-group`,"data-variant":i??`ghost`,"data-color":o??`primary`,"data-size":s??`md`,"data-spacing":c,"data-orientation":l,style:{"--gap":c},className:e(`group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch`,t),...d,children:r(a.Provider,{value:{variant:i,color:o,size:s,spacing:c,orientation:l},children:u})})}function ToggleGroupItem({className:o,children:s,variant:c=`ghost`,color:l=`primary`,size:u=`md`,...d}){let f=i.useContext(a);return r(n.Item,{"data-slot":`toggle-group-item`,"data-variant":f.variant||c,"data-color":f.color||l,"data-size":f.size||u,"data-spacing":f.spacing,className:e(`shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg`,`group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t`,`group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=secondary]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=secondary]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=secondary]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=secondary]:first:border-t`,t({variant:f.variant||c,color:f.color||l,size:f.size||u}),o),...d,children:s})}export{ToggleGroup,ToggleGroupItem};
|
|
2
2
|
//# sourceMappingURL=toggle-group.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-group.js","names":["ToggleGroupPrimitive"],"sources":["../../src/components/toggle-group.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport type { VariantProps } from 'class-variance-authority'\nimport { ToggleGroup as ToggleGroupPrimitive } from 'radix-ui'\n\nimport { cn } from '../lib/utils'\nimport { toggleVariants } from './toggle'\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: 'horizontal' | 'vertical'\n }\n>({\n size: 'md',\n variant: 'ghost',\n color: 'primary',\n spacing: 0,\n orientation: 'horizontal'\n})\n\nexport type ToggleGroupProps = React.ComponentProps<typeof ToggleGroupPrimitive.Root> &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: 'horizontal' | 'vertical'\n }\n\nexport type ToggleGroupItemProps = React.ComponentProps<typeof ToggleGroupPrimitive.Item> &\n VariantProps<typeof toggleVariants>\n\nfunction ToggleGroup({\n className,\n variant,\n color,\n size,\n spacing = 0,\n orientation = 'horizontal',\n children,\n ...props\n}: ToggleGroupProps) {\n return (\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={variant ?? 'ghost'}\n data-color={color ?? 'primary'}\n data-size={size ?? 'md'}\n data-spacing={spacing}\n data-orientation={orientation}\n style={{ '--gap': spacing } as React.CSSProperties}\n className={cn(\n 'group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch',\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider value={{ variant, color, size, spacing, orientation }}>\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = 'ghost',\n color = 'primary',\n size = 'md',\n ...props\n}: ToggleGroupItemProps) {\n const context = React.useContext(ToggleGroupContext)\n\n return (\n <ToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n data-variant={context.variant || variant}\n data-color={context.color || color}\n data-size={context.size || size}\n data-spacing={context.spacing}\n className={cn(\n 'shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg
|
|
1
|
+
{"version":3,"file":"toggle-group.js","names":["ToggleGroupPrimitive"],"sources":["../../src/components/toggle-group.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport type { VariantProps } from 'class-variance-authority'\nimport { ToggleGroup as ToggleGroupPrimitive } from 'radix-ui'\n\nimport { cn } from '../lib/utils'\nimport { toggleVariants } from './toggle'\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: 'horizontal' | 'vertical'\n }\n>({\n size: 'md',\n variant: 'ghost',\n color: 'primary',\n spacing: 0,\n orientation: 'horizontal'\n})\n\nexport type ToggleGroupProps = React.ComponentProps<typeof ToggleGroupPrimitive.Root> &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: 'horizontal' | 'vertical'\n }\n\nexport type ToggleGroupItemProps = React.ComponentProps<typeof ToggleGroupPrimitive.Item> &\n VariantProps<typeof toggleVariants>\n\nfunction ToggleGroup({\n className,\n variant,\n color,\n size,\n spacing = 0,\n orientation = 'horizontal',\n children,\n ...props\n}: ToggleGroupProps) {\n return (\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={variant ?? 'ghost'}\n data-color={color ?? 'primary'}\n data-size={size ?? 'md'}\n data-spacing={spacing}\n data-orientation={orientation}\n style={{ '--gap': spacing } as React.CSSProperties}\n className={cn(\n 'group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch',\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider value={{ variant, color, size, spacing, orientation }}>\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = 'ghost',\n color = 'primary',\n size = 'md',\n ...props\n}: ToggleGroupItemProps) {\n const context = React.useContext(ToggleGroupContext)\n\n return (\n <ToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n data-variant={context.variant || variant}\n data-color={context.color || color}\n data-size={context.size || size}\n data-spacing={context.spacing}\n className={cn(\n 'shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg',\n 'group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t',\n 'group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=secondary]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=secondary]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=secondary]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=secondary]:first:border-t',\n toggleVariants({\n variant: context.variant || variant,\n color: context.color || color,\n size: context.size || size\n }),\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n )\n}\n\nexport { ToggleGroup, ToggleGroupItem }\n"],"mappings":"iOAQA,MAAM,EAAqB,EAAM,cAK/B,CACA,KAAM,KACN,QAAS,QACT,MAAO,UACP,QAAS,EACT,YAAa,YACf,CAAC,EAWD,SAAS,YAAY,CACnB,YACA,UACA,QACA,OACA,UAAU,EACV,cAAc,aACd,WACA,GAAG,GACgB,CACnB,OACE,EAACA,EAAqB,KAAtB,CACE,YAAU,eACV,eAAc,GAAW,QACzB,aAAY,GAAS,UACrB,YAAW,GAAQ,KACnB,eAAc,EACd,mBAAkB,EAClB,MAAO,CAAE,QAAS,CAAQ,EAC1B,UAAW,EACT,oMACA,CACF,EACA,GAAI,EAEJ,SAAA,EAAC,EAAmB,SAApB,CAA6B,MAAO,CAAE,UAAS,QAAO,OAAM,UAAS,aAAY,EAC9E,UAC0B,CAAA,CACJ,CAAA,CAE/B,CAEA,SAAS,gBAAgB,CACvB,YACA,WACA,UAAU,QACV,QAAQ,UACR,OAAO,KACP,GAAG,GACoB,CACvB,IAAM,EAAU,EAAM,WAAW,CAAkB,EAEnD,OACE,EAACA,EAAqB,KAAtB,CACE,YAAU,oBACV,eAAc,EAAQ,SAAW,EACjC,aAAY,EAAQ,OAAS,EAC7B,YAAW,EAAQ,MAAQ,EAC3B,eAAc,EAAQ,QACtB,UAAW,EACT,yZACA,8VACA,sWACA,EAAe,CACb,QAAS,EAAQ,SAAW,EAC5B,MAAO,EAAQ,OAAS,EACxB,KAAM,EAAQ,MAAQ,CACxB,CAAC,EACD,CACF,EACA,GAAI,EAEH,UACwB,CAAA,CAE/B"}
|
|
@@ -4,7 +4,7 @@ import { VariantProps } from "class-variance-authority";
|
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
//#region src/components/toggle.d.ts
|
|
6
6
|
declare const toggleVariants: (props?: ({
|
|
7
|
-
variant?: "ghost" | "outline" | null | undefined;
|
|
7
|
+
variant?: "ghost" | "outline" | "secondary" | null | undefined;
|
|
8
8
|
color?: "blue" | "brand" | "gray" | "green" | "indigo" | "pink" | "primary" | "red" | "yellow" | "zinc" | null | undefined;
|
|
9
9
|
size?: "lg" | "md" | "sm" | null | undefined;
|
|
10
10
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../rolldown-runtime-Bdj-bS2b.js";import{cn as e}from"../lib/utils.js";import{buttonColorVariants as t}from"../lib/button.js";import{Toggle as n}from"radix-ui";import{jsx as r}from"react/jsx-runtime";import{cva as i}from"class-variance-authority";const a=i(`group/toggle inline-flex items-center justify-center gap-1 rounded-full border border-transparent text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,{variants:{variant:{outline:`border-(--button-outline-border) bg-background text-(--button-outline-foreground) hover:bg-(--button-solid) hover:text-(--button-solid-foreground) data-[state=on]:bg-(--button-solid) data-[state=on]:text-(--button-solid-foreground)`,ghost:`text-(--button-ghost-foreground) hover:bg-(--button-ghost-hover) hover:text-(--button-ghost-foreground) data-[state=on]:bg-(--button-ghost-hover) data-[state=on]:text-(--button-ghost-foreground)`},color:t,size:{sm:`h-8 min-w-8 px-1.5 text-[0.8rem]`,md:`h-9 min-w-9 px-2`,lg:`h-10 min-w-10 px-2.5`}},defaultVariants:{variant:`ghost`,color:`primary`,size:`md`}});function Toggle({className:t,variant:i=`ghost`,color:o=`primary`,size:s=`md`,...c}){return r(n.Root,{"data-slot":`toggle`,"data-variant":i,"data-color":o,"data-size":s,className:e(a({variant:i,color:o,size:s,className:t})),...c})}export{Toggle,a as toggleVariants};
|
|
1
|
+
import"../rolldown-runtime-Bdj-bS2b.js";import{cn as e}from"../lib/utils.js";import{buttonColorVariants as t}from"../lib/button.js";import{Toggle as n}from"radix-ui";import{jsx as r}from"react/jsx-runtime";import{cva as i}from"class-variance-authority";const a=i(`group/toggle inline-flex items-center justify-center gap-1 rounded-full border border-transparent text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,{variants:{variant:{secondary:`border-border bg-background hover:bg-muted hover:text-foreground data-[state=on]:bg-muted data-[state=on]:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 dark:data-[state=on]:bg-input/50`,outline:`border-(--button-outline-border) bg-background text-(--button-outline-foreground) hover:bg-(--button-solid) hover:text-(--button-solid-foreground) data-[state=on]:bg-(--button-solid) data-[state=on]:text-(--button-solid-foreground)`,ghost:`text-(--button-ghost-foreground) hover:bg-(--button-ghost-hover) hover:text-(--button-ghost-foreground) data-[state=on]:bg-(--button-ghost-hover) data-[state=on]:text-(--button-ghost-foreground)`},color:t,size:{sm:`h-8 min-w-8 px-1.5 text-[0.8rem]`,md:`h-9 min-w-9 px-2`,lg:`h-10 min-w-10 px-2.5`}},defaultVariants:{variant:`ghost`,color:`primary`,size:`md`}});function Toggle({className:t,variant:i=`ghost`,color:o=`primary`,size:s=`md`,...c}){return r(n.Root,{"data-slot":`toggle`,"data-variant":i,"data-color":o,"data-size":s,className:e(a({variant:i,color:o,size:s,className:t})),...c})}export{Toggle,a as toggleVariants};
|
|
2
2
|
//# sourceMappingURL=toggle.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle.js","names":["TogglePrimitive"],"sources":["../../src/components/toggle.tsx"],"sourcesContent":["import type * as React from 'react'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { Toggle as TogglePrimitive } from 'radix-ui'\n\nimport { buttonColorVariants } from '../lib/button'\nimport { cn } from '../lib/utils'\n\nconst toggleVariants = cva(\n \"group/toggle inline-flex items-center justify-center gap-1 rounded-full border border-transparent text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n outline:\n 'border-(--button-outline-border) bg-background text-(--button-outline-foreground) hover:bg-(--button-solid) hover:text-(--button-solid-foreground) data-[state=on]:bg-(--button-solid) data-[state=on]:text-(--button-solid-foreground)',\n ghost:\n 'text-(--button-ghost-foreground) hover:bg-(--button-ghost-hover) hover:text-(--button-ghost-foreground) data-[state=on]:bg-(--button-ghost-hover) data-[state=on]:text-(--button-ghost-foreground)'\n },\n color: buttonColorVariants,\n size: {\n sm: 'h-8 min-w-8 px-1.5 text-[0.8rem]',\n md: 'h-9 min-w-9 px-2',\n lg: 'h-10 min-w-10 px-2.5'\n }\n },\n defaultVariants: {\n variant: 'ghost',\n color: 'primary',\n size: 'md'\n }\n }\n)\n\nexport type ToggleProps = React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>\n\nfunction Toggle({ className, variant = 'ghost', color = 'primary', size = 'md', ...props }: ToggleProps) {\n return (\n <TogglePrimitive.Root\n data-slot=\"toggle\"\n data-variant={variant}\n data-color={color}\n data-size={size}\n className={cn(toggleVariants({ variant, color, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Toggle, toggleVariants }\n"],"mappings":"6PAQA,MAAM,EAAiB,EACrB,shBACA,CACE,SAAU,CACR,QAAS,CACP,QACE,0OACF,MACE,oMACJ,EACA,MAAO,EACP,KAAM,CACJ,GAAI,mCACJ,GAAI,mBACJ,GAAI,sBACN,CACF,EACA,gBAAiB,CACf,QAAS,QACT,MAAO,UACP,KAAM,IACR,CACF,CACF,EAIA,SAAS,OAAO,CAAE,YAAW,UAAU,QAAS,QAAQ,UAAW,OAAO,KAAM,GAAG,GAAsB,CACvG,OACE,EAACA,EAAgB,KAAjB,CACE,YAAU,SACV,eAAc,EACd,aAAY,EACZ,YAAW,EACX,UAAW,EAAG,EAAe,CAAE,UAAS,QAAO,OAAM,WAAU,CAAC,CAAC,EACjE,GAAI,CACL,CAAA,CAEL"}
|
|
1
|
+
{"version":3,"file":"toggle.js","names":["TogglePrimitive"],"sources":["../../src/components/toggle.tsx"],"sourcesContent":["import type * as React from 'react'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { Toggle as TogglePrimitive } from 'radix-ui'\n\nimport { buttonColorVariants } from '../lib/button'\nimport { cn } from '../lib/utils'\n\nconst toggleVariants = cva(\n \"group/toggle inline-flex items-center justify-center gap-1 rounded-full border border-transparent text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n secondary:\n 'border-border bg-background hover:bg-muted hover:text-foreground data-[state=on]:bg-muted data-[state=on]:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 dark:data-[state=on]:bg-input/50',\n outline:\n 'border-(--button-outline-border) bg-background text-(--button-outline-foreground) hover:bg-(--button-solid) hover:text-(--button-solid-foreground) data-[state=on]:bg-(--button-solid) data-[state=on]:text-(--button-solid-foreground)',\n ghost:\n 'text-(--button-ghost-foreground) hover:bg-(--button-ghost-hover) hover:text-(--button-ghost-foreground) data-[state=on]:bg-(--button-ghost-hover) data-[state=on]:text-(--button-ghost-foreground)'\n },\n color: buttonColorVariants,\n size: {\n sm: 'h-8 min-w-8 px-1.5 text-[0.8rem]',\n md: 'h-9 min-w-9 px-2',\n lg: 'h-10 min-w-10 px-2.5'\n }\n },\n defaultVariants: {\n variant: 'ghost',\n color: 'primary',\n size: 'md'\n }\n }\n)\n\nexport type ToggleProps = React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>\n\nfunction Toggle({ className, variant = 'ghost', color = 'primary', size = 'md', ...props }: ToggleProps) {\n return (\n <TogglePrimitive.Root\n data-slot=\"toggle\"\n data-variant={variant}\n data-color={color}\n data-size={size}\n className={cn(toggleVariants({ variant, color, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Toggle, toggleVariants }\n"],"mappings":"6PAQA,MAAM,EAAiB,EACrB,shBACA,CACE,SAAU,CACR,QAAS,CACP,UACE,uNACF,QACE,0OACF,MACE,oMACJ,EACA,MAAO,EACP,KAAM,CACJ,GAAI,mCACJ,GAAI,mBACJ,GAAI,sBACN,CACF,EACA,gBAAiB,CACf,QAAS,QACT,MAAO,UACP,KAAM,IACR,CACF,CACF,EAIA,SAAS,OAAO,CAAE,YAAW,UAAU,QAAS,QAAQ,UAAW,OAAO,KAAM,GAAG,GAAsB,CACvG,OACE,EAACA,EAAgB,KAAjB,CACE,YAAU,SACV,eAAc,EACd,aAAY,EACZ,YAAW,EACX,UAAW,EAAG,EAAe,CAAE,UAAS,QAAO,OAAM,WAAU,CAAC,CAAC,EACjE,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -46,10 +46,12 @@ To set up a consumer project after installing `@uselets/ui`, run `bun uselets in
|
|
|
46
46
|
- Prefer barrel imports for common app usage and readability.
|
|
47
47
|
- Use module subpaths when you want a single module or when the user asks for the exact import path.
|
|
48
48
|
- Use `@uselets/ui/hooks/<hook-module>` for dedicated hook subpaths, not legacy `@uselets/ui/use-*` paths.
|
|
49
|
-
- Recommend importing Tailwind
|
|
49
|
+
- Recommend importing Tailwind and one theme stylesheet once in the app global CSS. Use `@uselets/ui/themes/max.css` for Max apps or `@uselets/ui/themes/gomax.css` for Gomax apps.
|
|
50
50
|
- Recommend `@source '../node_modules/@uselets/ui/dist';` when Tailwind needs to generate classes used by installed `@uselets/ui` components.
|
|
51
51
|
- Treat `@uselets/ui/themes/gomax.css` as the GoMax Figma-backed palette, exposed through the same public color families as the Max theme.
|
|
52
|
-
- Recommend `@fontsource-variable/inter` when matching the package typography setup.
|
|
52
|
+
- Recommend `@fontsource-variable/inter` when matching the package typography setup. Import it once from the
|
|
53
|
+
app's entry file (`import '@fontsource-variable/inter'` in `app/layout.tsx`, `pages/_app.tsx`, or `src/main.tsx`),
|
|
54
|
+
not via `@import` in CSS — some bundlers, including Next.js, don't resolve third-party CSS `@import`s reliably.
|
|
53
55
|
- Recommend `@uselets/ui/postcss.config` when the app needs the package PostCSS preset for Tailwind v4.
|
|
54
56
|
- For tooltip-heavy apps, wrap the app with `TooltipProvider`; use `Tooltip label={...}` for common trigger/content usage and `TooltipRoot` only when manual composition is needed.
|
|
55
57
|
- Use `UnstyledButton` when button semantics are needed without `Button` variants; it provides reset styles, pointer cursor, focus ring, default `type="button"`, and `asChild`.
|
|
@@ -192,9 +192,10 @@ Unless noted otherwise, each module also exports its public `*Props` types from
|
|
|
192
192
|
- Exports: `Label`
|
|
193
193
|
- `toggle`
|
|
194
194
|
- Exports: `Toggle`, `toggleVariants`
|
|
195
|
-
- Notes: supports `color: UIColor` using the same color variants as `Button`
|
|
195
|
+
- Notes: `secondary`, `outline`, and `ghost` variants; supports `color: UIColor` using the same color variants as `Button`
|
|
196
196
|
- `toggle-group`
|
|
197
197
|
- Exports: `ToggleGroup`, `ToggleGroupItem`
|
|
198
|
+
- Notes: shares `toggleVariants` with `Toggle` (`secondary`, `outline`, `ghost`)
|
|
198
199
|
|
|
199
200
|
## Overlays and floating UI
|
|
200
201
|
|
|
@@ -53,12 +53,12 @@ Run the package setup command from the project root to install dependencies, con
|
|
|
53
53
|
bun uselets init
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
The command asks for the package theme, defaults the global CSS path to `src/styles/globals.css`, creates that CSS file when missing, preserves an existing `postcss.config.mjs`, and asks whether to install the agent skill.
|
|
56
|
+
The command asks for the package theme, defaults the global CSS path to `src/styles/globals.css`, creates that CSS file when missing, preserves an existing `postcss.config.mjs`, and asks whether to install the agent skill. It also detects a conventional app entry file (`app/layout.tsx`, `pages/_app.tsx`, `src/main.tsx`, `src/index.tsx`, and `.jsx` variants) and inserts `import '@fontsource-variable/inter'` there, or asks for the entry file path when none is found. Use `--entry <path>` to set it explicitly for non-interactive setups.
|
|
57
57
|
|
|
58
58
|
For non-interactive setup, provide explicit options:
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
bun uselets init --theme max --css src/styles/globals.css --no-install-skill
|
|
61
|
+
bun uselets init --theme max --css src/styles/globals.css --entry app/layout.tsx --no-install-skill
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
## Agent skill installation
|
|
@@ -99,16 +99,22 @@ Use `bun uselets skill --agent codex` or `bun uselets skill --agent claude` to i
|
|
|
99
99
|
|
|
100
100
|
## Base setup
|
|
101
101
|
|
|
102
|
-
Import Tailwind
|
|
102
|
+
Import Tailwind and one package theme once in the app global stylesheet:
|
|
103
103
|
|
|
104
104
|
```css
|
|
105
105
|
@import 'tailwindcss';
|
|
106
106
|
@import '@uselets/ui/themes/max.css';
|
|
107
|
-
@import '@fontsource-variable/inter';
|
|
108
107
|
```
|
|
109
108
|
|
|
110
109
|
For GoMax apps, import `@uselets/ui/themes/gomax.css` instead.
|
|
111
110
|
|
|
111
|
+
Import the Inter font once from the app's entry file, not from CSS (some bundlers, including Next.js, don't resolve third-party CSS `@import`s reliably):
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// app/layout.tsx (or src/main.tsx, pages/_app.tsx, ...)
|
|
115
|
+
import '@fontsource-variable/inter'
|
|
116
|
+
```
|
|
117
|
+
|
|
112
118
|
If the app needs Tailwind v4 PostCSS setup, reuse the package preset:
|
|
113
119
|
|
|
114
120
|
```js
|
|
@@ -198,7 +204,8 @@ Use these package-level helpers when relevant:
|
|
|
198
204
|
- `Toaster`
|
|
199
205
|
- Mount near the app root before calling `toast(...)`.
|
|
200
206
|
- `ThemeProvider`
|
|
201
|
-
- Provide package theme state for `useTheme` and `ModeToggle`.
|
|
207
|
+
- Provide package theme state for `useTheme` and `ModeToggle`. Accepts `defaultTheme`, `storageKey`, and
|
|
208
|
+
`disableTransitionOnChange` (suppresses CSS transitions during a theme switch, matching `next-themes`).
|
|
202
209
|
|
|
203
210
|
`Field` automatically shares one generated control id with `FieldLabel` and labelable descendants such as
|
|
204
211
|
`Input`, `Textarea`, `SelectTrigger`, `NativeSelect`, `Checkbox`, `Switch`, `RadioGroupItem`, and related input
|
|
@@ -241,7 +248,7 @@ import { ModeToggle, ThemeProvider } from '@uselets/ui/theme'
|
|
|
241
248
|
|
|
242
249
|
export function AppRoot({ children }: { children: React.ReactNode }) {
|
|
243
250
|
return (
|
|
244
|
-
<ThemeProvider defaultTheme="system">
|
|
251
|
+
<ThemeProvider defaultTheme="system" disableTransitionOnChange>
|
|
245
252
|
<ModeToggle />
|
|
246
253
|
{children}
|
|
247
254
|
</ThemeProvider>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uselets/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "React component library for the LET'S design system.",
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@base-ui/react": "1.6.0",
|
|
62
|
-
"@fontsource-variable/inter": "5.
|
|
62
|
+
"@fontsource-variable/inter": "5.3.0",
|
|
63
63
|
"@react-input/mask": "2.0.4",
|
|
64
|
-
"@tabler/icons-react": "3.
|
|
64
|
+
"@tabler/icons-react": "3.46.0",
|
|
65
65
|
"@tanstack/react-table": "8.21.3",
|
|
66
66
|
"class-variance-authority": "0.7.1",
|
|
67
67
|
"clsx": "2.1.1",
|
|
@@ -71,13 +71,13 @@
|
|
|
71
71
|
"embla-carousel-react": "8.6.0",
|
|
72
72
|
"input-otp": "1.4.2",
|
|
73
73
|
"next-themes": "0.4.6",
|
|
74
|
-
"radix-ui": "1.6.
|
|
74
|
+
"radix-ui": "1.6.7",
|
|
75
75
|
"react-day-picker": "10.0.1",
|
|
76
|
-
"react-dropzone": "
|
|
76
|
+
"react-dropzone": "19.1.1",
|
|
77
77
|
"react-phone-number-input": "3.4.17",
|
|
78
78
|
"react-resizable-panels": "4.12.2",
|
|
79
|
-
"recharts": "3.
|
|
80
|
-
"shadcn": "4.
|
|
79
|
+
"recharts": "3.10.1",
|
|
80
|
+
"shadcn": "4.16.0",
|
|
81
81
|
"sonner": "2.0.7",
|
|
82
82
|
"tailwind-merge": "3.6.0",
|
|
83
83
|
"tailwind-scrollbar": "4.0.2",
|
|
@@ -91,14 +91,14 @@
|
|
|
91
91
|
"@bosh-code/tsdown-plugin-tailwindcss": "1.0.1",
|
|
92
92
|
"@tailwindcss/postcss": "4.3.3",
|
|
93
93
|
"@testing-library/react": "16.3.2",
|
|
94
|
-
"@tsdown/css": "0.22.
|
|
95
|
-
"@turbo/gen": "2.10.
|
|
96
|
-
"@types/node": "26.1.
|
|
94
|
+
"@tsdown/css": "0.22.14",
|
|
95
|
+
"@turbo/gen": "2.10.7",
|
|
96
|
+
"@types/node": "26.1.2",
|
|
97
97
|
"@types/react": "19.2.17",
|
|
98
98
|
"@types/react-dom": "19.2.3",
|
|
99
|
-
"jsdom": "
|
|
99
|
+
"jsdom": "30.0.0",
|
|
100
100
|
"tailwindcss": "4.3.3",
|
|
101
|
-
"tsdown": "0.22.
|
|
101
|
+
"tsdown": "0.22.14",
|
|
102
102
|
"typescript": "7.0.2",
|
|
103
103
|
"vitest": "4.1.10"
|
|
104
104
|
}
|
|
@@ -46,10 +46,12 @@ To set up a consumer project after installing `@uselets/ui`, run `bun uselets in
|
|
|
46
46
|
- Prefer barrel imports for common app usage and readability.
|
|
47
47
|
- Use module subpaths when you want a single module or when the user asks for the exact import path.
|
|
48
48
|
- Use `@uselets/ui/hooks/<hook-module>` for dedicated hook subpaths, not legacy `@uselets/ui/use-*` paths.
|
|
49
|
-
- Recommend importing Tailwind
|
|
49
|
+
- Recommend importing Tailwind and one theme stylesheet once in the app global CSS. Use `@uselets/ui/themes/max.css` for Max apps or `@uselets/ui/themes/gomax.css` for Gomax apps.
|
|
50
50
|
- Recommend `@source '../node_modules/@uselets/ui/dist';` when Tailwind needs to generate classes used by installed `@uselets/ui` components.
|
|
51
51
|
- Treat `@uselets/ui/themes/gomax.css` as the GoMax Figma-backed palette, exposed through the same public color families as the Max theme.
|
|
52
|
-
- Recommend `@fontsource-variable/inter` when matching the package typography setup.
|
|
52
|
+
- Recommend `@fontsource-variable/inter` when matching the package typography setup. Import it once from the
|
|
53
|
+
app's entry file (`import '@fontsource-variable/inter'` in `app/layout.tsx`, `pages/_app.tsx`, or `src/main.tsx`),
|
|
54
|
+
not via `@import` in CSS — some bundlers, including Next.js, don't resolve third-party CSS `@import`s reliably.
|
|
53
55
|
- Recommend `@uselets/ui/postcss.config` when the app needs the package PostCSS preset for Tailwind v4.
|
|
54
56
|
- For tooltip-heavy apps, wrap the app with `TooltipProvider`; use `Tooltip label={...}` for common trigger/content usage and `TooltipRoot` only when manual composition is needed.
|
|
55
57
|
- Use `UnstyledButton` when button semantics are needed without `Button` variants; it provides reset styles, pointer cursor, focus ring, default `type="button"`, and `asChild`.
|
|
@@ -192,9 +192,10 @@ Unless noted otherwise, each module also exports its public `*Props` types from
|
|
|
192
192
|
- Exports: `Label`
|
|
193
193
|
- `toggle`
|
|
194
194
|
- Exports: `Toggle`, `toggleVariants`
|
|
195
|
-
- Notes: supports `color: UIColor` using the same color variants as `Button`
|
|
195
|
+
- Notes: `secondary`, `outline`, and `ghost` variants; supports `color: UIColor` using the same color variants as `Button`
|
|
196
196
|
- `toggle-group`
|
|
197
197
|
- Exports: `ToggleGroup`, `ToggleGroupItem`
|
|
198
|
+
- Notes: shares `toggleVariants` with `Toggle` (`secondary`, `outline`, `ghost`)
|
|
198
199
|
|
|
199
200
|
## Overlays and floating UI
|
|
200
201
|
|
|
@@ -53,12 +53,12 @@ Run the package setup command from the project root to install dependencies, con
|
|
|
53
53
|
bun uselets init
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
The command asks for the package theme, defaults the global CSS path to `src/styles/globals.css`, creates that CSS file when missing, preserves an existing `postcss.config.mjs`, and asks whether to install the agent skill.
|
|
56
|
+
The command asks for the package theme, defaults the global CSS path to `src/styles/globals.css`, creates that CSS file when missing, preserves an existing `postcss.config.mjs`, and asks whether to install the agent skill. It also detects a conventional app entry file (`app/layout.tsx`, `pages/_app.tsx`, `src/main.tsx`, `src/index.tsx`, and `.jsx` variants) and inserts `import '@fontsource-variable/inter'` there, or asks for the entry file path when none is found. Use `--entry <path>` to set it explicitly for non-interactive setups.
|
|
57
57
|
|
|
58
58
|
For non-interactive setup, provide explicit options:
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
bun uselets init --theme max --css src/styles/globals.css --no-install-skill
|
|
61
|
+
bun uselets init --theme max --css src/styles/globals.css --entry app/layout.tsx --no-install-skill
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
## Agent skill installation
|
|
@@ -99,16 +99,22 @@ Use `bun uselets skill --agent codex` or `bun uselets skill --agent claude` to i
|
|
|
99
99
|
|
|
100
100
|
## Base setup
|
|
101
101
|
|
|
102
|
-
Import Tailwind
|
|
102
|
+
Import Tailwind and one package theme once in the app global stylesheet:
|
|
103
103
|
|
|
104
104
|
```css
|
|
105
105
|
@import 'tailwindcss';
|
|
106
106
|
@import '@uselets/ui/themes/max.css';
|
|
107
|
-
@import '@fontsource-variable/inter';
|
|
108
107
|
```
|
|
109
108
|
|
|
110
109
|
For GoMax apps, import `@uselets/ui/themes/gomax.css` instead.
|
|
111
110
|
|
|
111
|
+
Import the Inter font once from the app's entry file, not from CSS (some bundlers, including Next.js, don't resolve third-party CSS `@import`s reliably):
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// app/layout.tsx (or src/main.tsx, pages/_app.tsx, ...)
|
|
115
|
+
import '@fontsource-variable/inter'
|
|
116
|
+
```
|
|
117
|
+
|
|
112
118
|
If the app needs Tailwind v4 PostCSS setup, reuse the package preset:
|
|
113
119
|
|
|
114
120
|
```js
|
|
@@ -198,7 +204,8 @@ Use these package-level helpers when relevant:
|
|
|
198
204
|
- `Toaster`
|
|
199
205
|
- Mount near the app root before calling `toast(...)`.
|
|
200
206
|
- `ThemeProvider`
|
|
201
|
-
- Provide package theme state for `useTheme` and `ModeToggle`.
|
|
207
|
+
- Provide package theme state for `useTheme` and `ModeToggle`. Accepts `defaultTheme`, `storageKey`, and
|
|
208
|
+
`disableTransitionOnChange` (suppresses CSS transitions during a theme switch, matching `next-themes`).
|
|
202
209
|
|
|
203
210
|
`Field` automatically shares one generated control id with `FieldLabel` and labelable descendants such as
|
|
204
211
|
`Input`, `Textarea`, `SelectTrigger`, `NativeSelect`, `Checkbox`, `Switch`, `RadioGroupItem`, and related input
|
|
@@ -241,7 +248,7 @@ import { ModeToggle, ThemeProvider } from '@uselets/ui/theme'
|
|
|
241
248
|
|
|
242
249
|
export function AppRoot({ children }: { children: React.ReactNode }) {
|
|
243
250
|
return (
|
|
244
|
-
<ThemeProvider defaultTheme="system">
|
|
251
|
+
<ThemeProvider defaultTheme="system" disableTransitionOnChange>
|
|
245
252
|
<ModeToggle />
|
|
246
253
|
{children}
|
|
247
254
|
</ThemeProvider>
|