artharexian-ui 0.2.11 → 0.3.2

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.
Files changed (35) hide show
  1. package/cli/index.mjs +164 -68
  2. package/package.json +5 -17
  3. package/src/styles/style.css +136 -136
  4. package/src/styles/variables.css +408 -408
  5. package/dist/artharexian-ui.css +0 -1
  6. package/dist/artharexian-ui.d.ts +0 -53
  7. package/dist/artharexian-ui.es.js +0 -38
  8. package/dist/artharexian-ui.umd.js +0 -1
  9. package/src/components/CheckboxBase.vue +0 -69
  10. package/src/components/SwitchBase.vue +0 -71
  11. package/src/components/ThemeToggle.vue +0 -30
  12. package/src/components/button-base/ButtonBase.vue +0 -82
  13. package/src/components/button-base/index.stories.ts +0 -108
  14. package/src/components/button-base/index.ts +0 -2
  15. package/src/components/button-base/meta.json +0 -10
  16. package/src/components/button-base/style.css +0 -2
  17. package/src/components/button-base/types.ts +0 -10
  18. package/src/components/card-base/CardBase.vue +0 -23
  19. package/src/components/card-base/CardContent.vue +0 -15
  20. package/src/components/card-base/CardDescription.vue +0 -18
  21. package/src/components/card-base/CardFooter.vue +0 -11
  22. package/src/components/card-base/CardHeader.vue +0 -14
  23. package/src/components/card-base/CardTitle.vue +0 -19
  24. package/src/components/input-base/InputBase.vue +0 -70
  25. package/src/components/input-base/types.ts +0 -7
  26. package/src/components/range-base/RangeBase.vue +0 -166
  27. package/src/components/range-base/RangeOutput.vue +0 -17
  28. package/src/components/range-base/types.ts +0 -16
  29. package/src/components/tabs/TabsBase.vue +0 -21
  30. package/src/components/tabs/TabsIndicator.vue +0 -18
  31. package/src/components/tabs/TabsList.vue +0 -28
  32. package/src/components/tabs/TabsPanel.vue +0 -16
  33. package/src/components/tabs/TabsTab.vue +0 -49
  34. package/src/components/tabs/context.ts +0 -12
  35. package/src/components/tabs/types.ts +0 -6
package/cli/index.mjs CHANGED
@@ -3,6 +3,7 @@ import fs from 'node:fs'
3
3
  import path from 'node:path'
4
4
  import process from 'node:process'
5
5
  import { fileURLToPath } from 'node:url'
6
+ import https from 'node:https'
6
7
 
7
8
  const __filename = fileURLToPath(import.meta.url)
8
9
  const __dirname = path.dirname(__filename)
@@ -11,21 +12,76 @@ const args = process.argv.slice(2)
11
12
  const command = args[0]
12
13
  const component = args[1]
13
14
 
14
- // INIT_CWD is set by npm to the directory where npm install was run
15
15
  const cwd = process.env.INIT_CWD || process.cwd()
16
16
 
17
- // Try installed package first, then fallback to local components (for development)
18
- let registryRoot = path.resolve(cwd, 'node_modules/artharexian-ui/src/components')
19
- if (!fs.existsSync(registryRoot)) {
20
- const localRegistry = path.resolve(__dirname, '../src/components')
21
- if (fs.existsSync(localRegistry)) {
22
- registryRoot = localRegistry
23
- }
17
+ // GitHub config
18
+ const GITHUB_REPO = 'r2-h/artharexian-ui'
19
+ const GITHUB_BRANCH = 'main'
20
+ const COMPONENTS_PATH = 'src/components'
21
+
22
+ const EXCLUDE_FILES = ['meta.json', 'index.stories.ts']
23
+
24
+ // Fetch JSON from GitHub
25
+ function fetchJSON(url) {
26
+ return new Promise((resolve, reject) => {
27
+ const options = {
28
+ headers: {
29
+ 'User-Agent': 'artharexian-ui-cli',
30
+ 'Accept': 'application/vnd.github.v3+json',
31
+ },
32
+ }
33
+ https
34
+ .get(url, options, (res) => {
35
+ if (res.statusCode !== 200) {
36
+ reject(new Error(`HTTP ${res.statusCode}: ${res.statusMessage}`))
37
+ return
38
+ }
39
+ let data = ''
40
+ res.on('data', (chunk) => (data += chunk))
41
+ res.on('end', () => {
42
+ try {
43
+ resolve(JSON.parse(data))
44
+ } catch (e) {
45
+ reject(new Error(`Failed to parse JSON: ${e.message}`))
46
+ }
47
+ })
48
+ })
49
+ .on('error', reject)
50
+ })
51
+ }
52
+
53
+ // Fetch file content from GitHub
54
+ function fetchFile(url) {
55
+ return new Promise((resolve, reject) => {
56
+ https
57
+ .get(url, (res) => {
58
+ let data = ''
59
+ res.on('data', (chunk) => (data += chunk))
60
+ res.on('end', () => resolve(data))
61
+ })
62
+ .on('error', reject)
63
+ })
64
+ }
65
+
66
+ // Get component files list from GitHub API
67
+ async function getComponentFiles(componentName) {
68
+ const url = `https://api.github.com/repos/${GITHUB_REPO}/contents/${COMPONENTS_PATH}/${componentName}?ref=${GITHUB_BRANCH}`
69
+ const data = await fetchJSON(url)
70
+ return data.filter((file) => file.type === 'file' && !EXCLUDE_FILES.includes(file.name))
71
+ }
72
+
73
+ // Download and save file
74
+ async function downloadFile(file, destPath) {
75
+ const content = await fetchFile(file.download_url)
76
+ fs.writeFileSync(destPath, content)
24
77
  }
25
78
 
79
+ // Copy directory locally (for development)
26
80
  function copyDir(src, dest) {
27
81
  fs.mkdirSync(dest, { recursive: true })
28
82
  for (const file of fs.readdirSync(src)) {
83
+ if (EXCLUDE_FILES.includes(file)) continue
84
+
29
85
  const s = path.join(src, file)
30
86
  const d = path.join(dest, file)
31
87
  if (fs.statSync(s).isDirectory()) {
@@ -36,99 +92,139 @@ function copyDir(src, dest) {
36
92
  }
37
93
  }
38
94
 
39
- function ensureCssImport() {
40
- const mainTs = path.resolve(cwd, 'src/main.ts')
41
- const mainJs = path.resolve(cwd, 'src/main.js')
42
- const mainFile = fs.existsSync(mainTs) ? mainTs : fs.existsSync(mainJs) ? mainJs : null
95
+ // Add component from GitHub
96
+ async function addComponent(componentName) {
97
+ const destDir = path.resolve(cwd, 'src/components/ui', componentName)
98
+ const stylesPath = path.resolve(cwd, 'src/styles')
43
99
 
44
- if (!mainFile) return
100
+ // Auto-install styles if not present
101
+ if (!fs.existsSync(stylesPath)) {
102
+ console.log('Styles not found. Installing...\n')
103
+ await copyStyles()
104
+ console.log('')
105
+ }
45
106
 
46
- let code = fs.readFileSync(mainFile, 'utf8')
107
+ console.log(`Fetching ${componentName} from GitHub...`)
47
108
 
48
- // Check if local styles import exists
49
- if (code.includes('./styles/style.css') || code.includes('@/styles/style.css')) return
109
+ try {
110
+ const files = await getComponentFiles(componentName)
111
+
112
+ if (files.length === 0) {
113
+ console.error(`Error: Component not found: ${componentName}`)
114
+ listComponents()
115
+ process.exit(1)
116
+ }
117
+
118
+ fs.mkdirSync(destDir, { recursive: true })
119
+
120
+ for (const file of files) {
121
+ const destPath = path.join(destDir, file.name)
122
+ await downloadFile(file, destPath)
123
+ console.log(` ✔ ${file.name}`)
124
+ }
125
+
126
+ console.log(`\n✔ ${componentName} added to src/components/ui/${componentName}`)
127
+ console.log('\nNext steps:')
128
+ console.log(` 1. Import: import { ${toPascalCase(componentName)} } from '@/components/ui/${componentName}'`)
129
+ console.log(' 2. Configure CSS variables (see docs)')
130
+ } catch (error) {
131
+ console.error(`Error: ${error.message}`)
132
+ console.error('\nMake sure you have internet connection and the component exists.')
133
+ process.exit(1)
134
+ }
135
+ }
50
136
 
51
- code = `import './styles/style.css'\n` + code
52
- fs.writeFileSync(mainFile, code)
53
- console.log(' Style import added to src/main')
137
+ // List available components
138
+ async function listComponents() {
139
+ console.log('Available components:')
140
+ try {
141
+ const url = `https://api.github.com/repos/${GITHUB_REPO}/contents/${COMPONENTS_PATH}?ref=${GITHUB_BRANCH}`
142
+ const data = await fetchJSON(url)
143
+ const components = data.filter((item) => item.type === 'dir').map((item) => item.name)
144
+ components.forEach((c) => console.log(` - ${c}`))
145
+ } catch (error) {
146
+ console.error(` (unable to fetch: ${error.message})`)
147
+ }
54
148
  }
55
149
 
56
- function copyStyles() {
57
- const stylesSrc = path.resolve(cwd, 'node_modules/artharexian-ui/src/styles')
150
+ // Copy styles from GitHub
151
+ async function copyStyles() {
58
152
  const stylesDst = path.resolve(cwd, 'src/styles')
59
153
 
60
- if (!fs.existsSync(stylesSrc)) {
61
- console.log('⚠ Styles not found in package')
62
- return
63
- }
154
+ console.log('Fetching styles from GitHub...')
155
+
156
+ try {
157
+ const url = `https://api.github.com/repos/${GITHUB_REPO}/contents/src/styles?ref=${GITHUB_BRANCH}`
158
+ const data = await fetchJSON(url)
159
+ const cssFiles = data.filter((file) => file.type === 'file' && file.name.endsWith('.css'))
64
160
 
65
- fs.mkdirSync(stylesDst, { recursive: true })
66
-
67
- // Copy all CSS files from package to project
68
- for (const file of fs.readdirSync(stylesSrc)) {
69
- if (file.endsWith('.css')) {
70
- const srcFile = path.join(stylesSrc, file)
71
- const dstFile = path.join(stylesDst, file)
72
- fs.copyFileSync(srcFile, dstFile)
73
- console.log(`✔ ${file} installed to src/styles/${file}`)
161
+ fs.mkdirSync(stylesDst, { recursive: true })
162
+
163
+ for (const file of cssFiles) {
164
+ const destPath = path.join(stylesDst, file.name)
165
+ await downloadFile(file, destPath)
166
+ console.log(` ✔ ${file.name}`)
74
167
  }
168
+
169
+ console.log('✔ Styles installed')
170
+ } catch (error) {
171
+ console.error(`Error: ${error.message}`)
172
+ process.exit(1)
75
173
  }
76
174
  }
77
175
 
176
+ // Helper functions
177
+ function capitalize(str) {
178
+ return str.charAt(0).toUpperCase() + str.slice(1)
179
+ }
180
+
181
+ function toPascalCase(str) {
182
+ return str
183
+ .split('-')
184
+ .map((part) => capitalize(part))
185
+ .join('')
186
+ }
187
+
188
+ // CLI commands
78
189
  if (!command) {
79
- console.log('Usage: artharexian-ui <add|eject|init> [component]')
190
+ console.log('Usage: artharexian-ui <add|eject|init|list> [component]')
80
191
  console.log('')
81
192
  console.log('Commands:')
82
- console.log(' add <component> Add a component to your project')
193
+ console.log(' add <component> Add a component to your project (from GitHub)')
83
194
  console.log(' eject <component> Alias for add (eject component source)')
84
- console.log(' init Initialize library (copy styles, configure)')
195
+ console.log(' init Initialize library (copy styles)')
196
+ console.log(' list List available components')
85
197
  console.log('')
86
198
  console.log('Examples:')
87
199
  console.log(' npx artharexian-ui add button-base')
200
+ console.log(' npx artharexian-ui list')
88
201
  console.log(' npx artharexian-ui init')
89
202
  process.exit(0)
90
203
  }
91
204
 
92
- // Handle init command (auto-run on npm install)
93
205
  if (command === 'init') {
94
206
  console.log('Initializing artharexian-ui...')
95
- copyStyles()
96
- ensureCssImport()
207
+ await copyStyles()
97
208
  console.log('')
98
209
  console.log('✔ artharexian-ui initialized successfully!')
99
210
  process.exit(0)
100
211
  }
101
212
 
102
- if (!component) {
103
- console.error('Error: Component name required')
104
- console.error('Usage: artharexian-ui add <component>')
105
- process.exit(1)
213
+ if (command === 'list') {
214
+ await listComponents()
215
+ process.exit(0)
106
216
  }
107
217
 
108
- const src = path.join(registryRoot, component)
109
-
110
- if (!fs.existsSync(src)) {
111
- console.error(`Error: Component not found: ${component}`)
112
- console.error('')
113
- console.error('Available components:')
114
- try {
115
- const components = fs.readdirSync(registryRoot)
116
- components.forEach((c) => console.error(` - ${c}`))
117
- } catch {
118
- console.error(' (unable to list registry)')
218
+ if (command === 'add' || command === 'eject') {
219
+ if (!component) {
220
+ console.error('Error: Component name required')
221
+ console.error('Usage: artharexian-ui add <component>')
222
+ process.exit(1)
119
223
  }
120
- process.exit(1)
224
+ await addComponent(component)
225
+ process.exit(0)
121
226
  }
122
227
 
123
- const dst = path.resolve(cwd, 'src/components/ui', component)
124
-
125
- copyDir(src, dst)
126
-
127
- console.log(`✔ ${component} added to src/components/ui/${component}`)
128
-
129
- ensureCssImport()
130
-
131
- console.log('')
132
- console.log('Next steps:')
133
- console.log(` 1. Import the component: import { ButtonBase } from '@/components/ui/${component}'`)
134
- console.log(' 2. Make sure your CSS variables are configured (see docs)')
228
+ console.error(`Unknown command: ${command}`)
229
+ console.error('Run without arguments for usage info')
230
+ process.exit(1)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "artharexian-ui",
3
3
  "description": "Vue 3 UI component library",
4
- "version": "0.2.11",
4
+ "version": "0.3.2",
5
5
  "license": "MIT",
6
6
  "private": false,
7
7
  "type": "module",
@@ -10,31 +10,21 @@
10
10
  "type": "git",
11
11
  "url": "git+https://github.com/r2-h/artharexian-ui.git"
12
12
  },
13
- "main": "./dist/artharexian-ui.umd.js",
14
- "module": "./dist/artharexian-ui.es.js",
15
- "types": "./dist/artharexian-ui.d.ts",
16
13
  "bin": {
17
14
  "artharexian-ui": "./cli/index.mjs"
18
15
  },
19
16
  "files": [
20
- "dist",
21
17
  "src/styles",
22
- "src/components",
23
- "cli"
18
+ "cli",
19
+ "!**/*.stories.ts",
20
+ "!**/meta.json"
24
21
  ],
25
22
  "exports": {
26
- ".": {
27
- "types": "./dist/artharexian-ui.d.ts",
28
- "import": "./dist/artharexian-ui.es.js",
29
- "require": "./dist/artharexian-ui.umd.js"
30
- },
31
- "./css": "./dist/artharexian-ui.css"
23
+ "./styles": "./src/styles/style.css"
32
24
  },
33
25
  "scripts": {
34
26
  "dev": "vite",
35
- "build": "vue-tsc -b && vite build",
36
27
  "format": "prettier --write .",
37
- "preview": "vite preview",
38
28
  "storybook": "storybook dev -p 6006",
39
29
  "build-storybook": "storybook build",
40
30
  "postinstall": "node ./cli/index.mjs init"
@@ -61,8 +51,6 @@
61
51
  "storybook": "^10.2.10",
62
52
  "typescript": "~5.9.3",
63
53
  "vite": "^7.3.1",
64
- "vite-plugin-css-injected-by-js": "^3.1.1",
65
- "vite-plugin-dts": "^3.6.4",
66
54
  "vitest": "^4.0.18",
67
55
  "vue": "^3.5.25",
68
56
  "vue-tsc": "^3.1.5"
@@ -1,136 +1,136 @@
1
- @import url('https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@14..36,300;14..36,400;14..36,500;14..36,600;14..36,700&display=swap');
2
- @import 'variables.css';
3
- @layer theme, base, components, utilities;
4
-
5
- @layer base {
6
- :root {
7
- &[data-theme='light'] {
8
- color-scheme: light;
9
- }
10
- &[data-theme='dark'] {
11
- color-scheme: dark;
12
- }
13
-
14
- color-scheme: light dark;
15
- scroll-behavior: smooth;
16
- font-size: 10px;
17
- font-family: 'DM Sans', sans-serif;
18
- }
19
-
20
- body {
21
- background: var(--background);
22
- color: var(--foreground);
23
- -webkit-font-smoothing: antialiased;
24
- font-size: 1.6rem;
25
- }
26
-
27
- *,
28
- *::before,
29
- *::after {
30
- box-sizing: border-box;
31
- margin: 0;
32
- padding: 0;
33
- border: 0 solid;
34
- }
35
-
36
- :disabled,
37
- [aria-busy='true'],
38
- .is-disabled {
39
- pointer-events: none;
40
- color: var(--color-neutral-500);
41
- opacity: 0.45;
42
- }
43
-
44
- h1,
45
- h2,
46
- h3,
47
- h4,
48
- h5,
49
- h6 {
50
- text-wrap: balance;
51
- font-size: inherit;
52
- font-weight: inherit;
53
- }
54
-
55
- textarea {
56
- resize: vertical;
57
- }
58
-
59
- img,
60
- picture,
61
- svg,
62
- video {
63
- display: block;
64
- max-width: 100%;
65
- height: auto;
66
- }
67
-
68
- input,
69
- button,
70
- textarea,
71
- select {
72
- font: inherit;
73
- }
74
-
75
- a {
76
- text-decoration: none;
77
- color: inherit;
78
- &:hover {
79
- text-decoration: underline;
80
- }
81
- }
82
-
83
- ol,
84
- ul,
85
- menu {
86
- list-style: none;
87
- }
88
- }
89
-
90
- @layer components {
91
- h1 {
92
- font-size: var(--text-2xl);
93
- }
94
- h2 {
95
- font-size: var(--text-xl);
96
- }
97
- h3 {
98
- font-size: var(--text-lg);
99
- }
100
- ::placeholder {
101
- color: var(--muted-foreground);
102
- }
103
-
104
- .font-xs {
105
- font-size: var(--text-xs);
106
- /* line-height: var(--leading-relaxed); */
107
- }
108
- .font-sm {
109
- font-size: var(--text-sm);
110
- /* line-height: var(--leading-normal); */
111
- }
112
- .font-base {
113
- font-size: var(--text-base);
114
- /* line-height: var(--leading-normal); */
115
- }
116
- .font-lg {
117
- font-size: var(--text-lg);
118
- /* line-height: var(--leading-normal); */
119
- }
120
- .font-xl {
121
- font-size: var(--text-xl);
122
- /* line-height: var(--leading-snug); */
123
- }
124
- .font-2xl {
125
- font-size: var(--text-2xl);
126
- /* line-height: var(--leading-tight); */
127
- }
128
- .font-3xl {
129
- font-size: var(--text-3xl);
130
- /* line-height: 1; */
131
- }
132
- .font-4xl {
133
- font-size: var(--text-4xl);
134
- /* line-height: 1; */
135
- }
136
- }
1
+ @import url('https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@14..36,300;14..36,400;14..36,500;14..36,600;14..36,700&display=swap');
2
+ @import 'variables.css';
3
+ @layer theme, base, components, utilities;
4
+
5
+ @layer base {
6
+ :root {
7
+ &[data-theme='light'] {
8
+ color-scheme: light;
9
+ }
10
+ &[data-theme='dark'] {
11
+ color-scheme: dark;
12
+ }
13
+
14
+ color-scheme: light dark;
15
+ scroll-behavior: smooth;
16
+ font-size: 10px;
17
+ font-family: 'DM Sans', sans-serif;
18
+ }
19
+
20
+ body {
21
+ background: var(--background);
22
+ color: var(--foreground);
23
+ -webkit-font-smoothing: antialiased;
24
+ font-size: 1.6rem;
25
+ }
26
+
27
+ *,
28
+ *::before,
29
+ *::after {
30
+ box-sizing: border-box;
31
+ margin: 0;
32
+ padding: 0;
33
+ border: 0 solid;
34
+ }
35
+
36
+ :disabled,
37
+ [aria-busy='true'],
38
+ .is-disabled {
39
+ pointer-events: none;
40
+ color: var(--color-neutral-500);
41
+ opacity: 0.45;
42
+ }
43
+
44
+ h1,
45
+ h2,
46
+ h3,
47
+ h4,
48
+ h5,
49
+ h6 {
50
+ text-wrap: balance;
51
+ font-size: inherit;
52
+ font-weight: inherit;
53
+ }
54
+
55
+ textarea {
56
+ resize: vertical;
57
+ }
58
+
59
+ img,
60
+ picture,
61
+ svg,
62
+ video {
63
+ display: block;
64
+ max-width: 100%;
65
+ height: auto;
66
+ }
67
+
68
+ input,
69
+ button,
70
+ textarea,
71
+ select {
72
+ font: inherit;
73
+ }
74
+
75
+ a {
76
+ text-decoration: none;
77
+ color: inherit;
78
+ &:hover {
79
+ text-decoration: underline;
80
+ }
81
+ }
82
+
83
+ ol,
84
+ ul,
85
+ menu {
86
+ list-style: none;
87
+ }
88
+ }
89
+
90
+ @layer components {
91
+ h1 {
92
+ font-size: var(--text-2xl);
93
+ }
94
+ h2 {
95
+ font-size: var(--text-xl);
96
+ }
97
+ h3 {
98
+ font-size: var(--text-lg);
99
+ }
100
+ ::placeholder {
101
+ color: var(--muted-foreground);
102
+ }
103
+
104
+ .font-xs {
105
+ font-size: var(--text-xs);
106
+ /* line-height: var(--leading-relaxed); */
107
+ }
108
+ .font-sm {
109
+ font-size: var(--text-sm);
110
+ /* line-height: var(--leading-normal); */
111
+ }
112
+ .font-base {
113
+ font-size: var(--text-base);
114
+ /* line-height: var(--leading-normal); */
115
+ }
116
+ .font-lg {
117
+ font-size: var(--text-lg);
118
+ /* line-height: var(--leading-normal); */
119
+ }
120
+ .font-xl {
121
+ font-size: var(--text-xl);
122
+ /* line-height: var(--leading-snug); */
123
+ }
124
+ .font-2xl {
125
+ font-size: var(--text-2xl);
126
+ /* line-height: var(--leading-tight); */
127
+ }
128
+ .font-3xl {
129
+ font-size: var(--text-3xl);
130
+ /* line-height: 1; */
131
+ }
132
+ .font-4xl {
133
+ font-size: var(--text-4xl);
134
+ /* line-height: 1; */
135
+ }
136
+ }