ui-thing 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/dist/index.js +264 -24
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
- package/src/commands/add.ts +5 -1
- package/src/comps.ts +91 -11
- package/src/types.ts +1 -0
- package/src/utils/config.ts +2 -0
- package/src/utils/uiConfigPrompt.ts +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ui-thing",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"description": "CLI used to add Nuxt 3 components to a project",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -41,31 +41,31 @@
|
|
|
41
41
|
"axios": "^1.7.2",
|
|
42
42
|
"boxen": "^7.1.1",
|
|
43
43
|
"build": "^0.1.4",
|
|
44
|
-
"c12": "^1.
|
|
44
|
+
"c12": "^1.11.1",
|
|
45
45
|
"commander": "^12.1.0",
|
|
46
46
|
"defu": "^6.1.4",
|
|
47
|
-
"execa": "^9.
|
|
47
|
+
"execa": "^9.3.0",
|
|
48
48
|
"figlet": "^1.7.0",
|
|
49
49
|
"fs-extra": "^11.2.0",
|
|
50
50
|
"kleur": "^4.1.5",
|
|
51
51
|
"lodash": "^4.17.21",
|
|
52
|
-
"nypm": "^0.3.
|
|
52
|
+
"nypm": "^0.3.9",
|
|
53
53
|
"ora": "^8.0.1",
|
|
54
54
|
"prompts": "^2.4.2"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@gmrchk/cli-testing-library": "^0.1.2",
|
|
58
|
-
"@ianvs/prettier-plugin-sort-imports": "^4.
|
|
58
|
+
"@ianvs/prettier-plugin-sort-imports": "^4.3.0",
|
|
59
59
|
"@types/figlet": "^1.5.8",
|
|
60
60
|
"@types/fs-extra": "^11.0.4",
|
|
61
|
-
"@types/lodash": "^4.17.
|
|
62
|
-
"@types/node": "^20.14.
|
|
61
|
+
"@types/lodash": "^4.17.6",
|
|
62
|
+
"@types/node": "^20.14.10",
|
|
63
63
|
"@types/prompts": "^2.4.9",
|
|
64
|
-
"@vitest/coverage-v8": "^
|
|
64
|
+
"@vitest/coverage-v8": "^2.0.1",
|
|
65
65
|
"magicast": "^0.3.4",
|
|
66
66
|
"tsup": "^8.1.0",
|
|
67
|
-
"typescript": "^5.
|
|
68
|
-
"vitest": "^
|
|
67
|
+
"typescript": "^5.5.3",
|
|
68
|
+
"vitest": "^2.0.1"
|
|
69
69
|
},
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
package/src/commands/add.ts
CHANGED
|
@@ -233,7 +233,11 @@ export const add = new Command()
|
|
|
233
233
|
// add plugins attached to the component
|
|
234
234
|
loop5: for (let j = 0; j < component.plugins.length; j++) {
|
|
235
235
|
const plugin = component.plugins[j];
|
|
236
|
-
const filePath = path.join(
|
|
236
|
+
const filePath = path.join(
|
|
237
|
+
currentDirectory,
|
|
238
|
+
uiConfig.pluginsLocation ?? plugin.dirPath,
|
|
239
|
+
plugin.fileName
|
|
240
|
+
);
|
|
237
241
|
// Check if the file exists
|
|
238
242
|
const exists = await fileExists(filePath);
|
|
239
243
|
if (exists && !uiConfig.force) {
|
package/src/comps.ts
CHANGED
|
@@ -388,7 +388,7 @@ export default [
|
|
|
388
388
|
fileName: "Card/Footer.vue",
|
|
389
389
|
dirPath: "components/UI",
|
|
390
390
|
fileContent:
|
|
391
|
-
'<template>\n <Primitive :class="styles({ class: props.class })" :as="as" :as-child="asChild">\n <slot />\n </Primitive>\n</template>\n\n<script lang="ts" setup>\n import { Primitive } from "radix-vue";\n import type { PrimitiveProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n PrimitiveProps & {\n /** Custom class(es) to add to the element */\n class?: any;\n }\n >(),\n { as: "div" }\n );\n\n const styles = tv({\n base: "flex items-center p-6
|
|
391
|
+
'<template>\n <Primitive :class="styles({ class: props.class })" :as="as" :as-child="asChild">\n <slot />\n </Primitive>\n</template>\n\n<script lang="ts" setup>\n import { Primitive } from "radix-vue";\n import type { PrimitiveProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n PrimitiveProps & {\n /** Custom class(es) to add to the element */\n class?: any;\n }\n >(),\n { as: "div" }\n );\n\n const styles = tv({\n base: "flex items-center p-6",\n });\n</script>\n',
|
|
392
392
|
},
|
|
393
393
|
{
|
|
394
394
|
fileName: "Card/Header.vue",
|
|
@@ -1030,7 +1030,7 @@ export default [
|
|
|
1030
1030
|
fileName: "FancyIcon.vue",
|
|
1031
1031
|
dirPath: "components/UI",
|
|
1032
1032
|
fileContent:
|
|
1033
|
-
'<template>\n <div :class="styles().base({ class: props.class, color, type, size, circle })">\n <slot :styles="styles().icon({ color, type, size, circle })">\n <Icon :name="icon" :class="styles().icon({ color, type, size, circle })" />\n </slot>\n </div>\n</template>\n\n<script lang="ts" setup>\n const props = withDefaults(\n defineProps<{\n class?: any;\n icon: string;\n color?: VariantProps<typeof styles>["color"];\n type?: VariantProps<typeof styles>["type"];\n size?: VariantProps<typeof styles>["size"];\n circle?: boolean;\n }>(),\n {\n color: "primary",\n type: "modern",\n size: "lg",\n circle: false,\n }\n );\n\n const styles = tv({\n slots: {\n base: "flex shrink-0 items-center justify-center",\n icon: "",\n },\n\n variants: {\n color: {\n primary: {\n base: "",\n icon: "",\n },\n success: {\n base: "",\n icon: "",\n },\n warning: {\n base: "",\n icon: "",\n },\n error: {\n base: "",\n icon: "",\n },\n info: {\n base: "",\n icon: "",\n },\n },\n type: {\n light: {\n base: "",\n icon: "",\n },\n dark: {\n base: "",\n icon: "",\n },\n modern: {\n base: "",\n icon: "",\n },\n },\n size: {\n sm: {\n base: "size-8",\n icon: "size-4",\n },\n md: {\n base: "size-10",\n icon: "size-5",\n },\n lg: {\n base: "size-12",\n icon: "size-6",\n },\n xl: {\n base: "size-14",\n icon: "size-7",\n },\n },\n circle: {\n true: {\n base: "rounded-full",\n },\n false: {\n base: "rounded-lg",\n },\n },\n },\n compoundVariants: [\n {\n color: "primary",\n type: "light",\n class: { base: "bg-primary/5
|
|
1033
|
+
'<template>\n <div :class="styles().base({ class: props.class, color, type, size, circle })">\n <slot :styles="styles().icon({ color, type, size, circle })">\n <Icon :name="icon" :class="styles().icon({ color, type, size, circle })" />\n </slot>\n </div>\n</template>\n\n<script lang="ts" setup>\n const props = withDefaults(\n defineProps<{\n class?: any;\n icon: string;\n color?: VariantProps<typeof styles>["color"];\n type?: VariantProps<typeof styles>["type"];\n size?: VariantProps<typeof styles>["size"];\n circle?: boolean;\n }>(),\n {\n color: "primary",\n type: "modern",\n size: "lg",\n circle: false,\n }\n );\n\n const styles = tv({\n slots: {\n base: "flex shrink-0 items-center justify-center",\n icon: "",\n },\n\n variants: {\n color: {\n primary: {\n base: "",\n icon: "",\n },\n success: {\n base: "",\n icon: "",\n },\n warning: {\n base: "",\n icon: "",\n },\n error: {\n base: "",\n icon: "",\n },\n info: {\n base: "",\n icon: "",\n },\n },\n type: {\n light: {\n base: "",\n icon: "",\n },\n dark: {\n base: "",\n icon: "",\n },\n modern: {\n base: "",\n icon: "",\n },\n },\n size: {\n sm: {\n base: "size-8",\n icon: "size-4",\n },\n md: {\n base: "size-10",\n icon: "size-5",\n },\n lg: {\n base: "size-12",\n icon: "size-6",\n },\n xl: {\n base: "size-14",\n icon: "size-7",\n },\n },\n circle: {\n true: {\n base: "rounded-full",\n },\n false: {\n base: "rounded-lg",\n },\n },\n },\n compoundVariants: [\n {\n color: "primary",\n type: "light",\n class: { base: "bg-primary/5", icon: "text-primary" },\n },\n {\n color: "success",\n type: "light",\n class: {\n base: "bg-green-500/10",\n icon: "text-green-600",\n },\n },\n {\n color: "warning",\n type: "light",\n class: { base: "bg-amber-500/10", icon: "text-amber-600" },\n },\n {\n color: "error",\n type: "light",\n class: { base: "bg-destructive/10", icon: "text-destructive" },\n },\n {\n color: "info",\n type: "light",\n class: { base: "bg-blue-500/10", icon: "text-blue-600" },\n },\n // Dark\n {\n color: "primary",\n type: "dark",\n class: { base: "bg-primary", icon: "text-primary-foreground" },\n },\n {\n color: "success",\n type: "dark",\n class: { base: "bg-green-600", icon: "text-green-50" },\n },\n {\n color: "warning",\n type: "dark",\n class: { base: "bg-amber-600", icon: "text-amber-50" },\n },\n {\n color: "error",\n type: "dark",\n class: { base: "bg-destructive", icon: "text-destructive-foreground" },\n },\n {\n color: "info",\n type: "dark",\n class: { base: "bg-blue-500", icon: "text-blue-50" },\n },\n // Modern\n {\n type: "modern",\n class: { base: "border bg-background", icon: "text-muted-foreground" },\n },\n ],\n defaultVariants: {\n color: "primary",\n type: "modern",\n size: "lg",\n circle: false,\n },\n });\n</script>\n',
|
|
1034
1034
|
},
|
|
1035
1035
|
],
|
|
1036
1036
|
utils: [],
|
|
@@ -1108,7 +1108,7 @@ export default [
|
|
|
1108
1108
|
fileName: "HoverCard/Arrow.vue",
|
|
1109
1109
|
dirPath: "components/UI",
|
|
1110
1110
|
fileContent:
|
|
1111
|
-
'<template>\n <HoverCardArrow :class="styles({ class: props.class })" v-bind="reactiveOmit(props, \'class\')" />\n</template>\n\n<script lang="ts" setup>\n import { HoverCardArrow } from "radix-vue";\n import type { HoverCardArrowProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n HoverCardArrowProps & {\n /** Custom class(es) to add to the parent */\n class?: any;\n }\n >(),\n {\n height: 5,\n width: 10,\n }\n );\n\n const styles = tv({\n base: "
|
|
1111
|
+
'<template>\n <HoverCardArrow :class="styles({ class: props.class })" v-bind="reactiveOmit(props, \'class\')" />\n</template>\n\n<script lang="ts" setup>\n import { HoverCardArrow } from "radix-vue";\n import type { HoverCardArrowProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n HoverCardArrowProps & {\n /** Custom class(es) to add to the parent */\n class?: any;\n }\n >(),\n {\n height: 5,\n width: 10,\n }\n );\n\n const styles = tv({\n base: "fill-popover",\n });\n</script>\n',
|
|
1112
1112
|
},
|
|
1113
1113
|
{
|
|
1114
1114
|
fileName: "HoverCard/Content.vue",
|
|
@@ -1148,7 +1148,7 @@ export default [
|
|
|
1148
1148
|
fileName: "Input.vue",
|
|
1149
1149
|
dirPath: "components/UI",
|
|
1150
1150
|
fileContent:
|
|
1151
|
-
'<template>\n <input v-bind="props" v-model="localModel" :class="styles({ class: props.class })"
|
|
1151
|
+
'<template>\n <input v-bind="props" v-model="localModel" :class="styles({ class: props.class })" >\n</template>\n\n<script lang="ts" setup>\n const props = withDefaults(\n defineProps<{\n class?: any;\n id?: string;\n name?: string;\n placeholder?: string;\n disabled?: boolean;\n required?: boolean;\n type?: string;\n modelValue?: any;\n }>(),\n { type: "text" }\n );\n const emits = defineEmits<{\n "update:modelValue": [value: any];\n }>();\n const localModel = useVModel(props, "modelValue", emits);\n\n const styles = tv({\n base: "form-input h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:px-1 file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground file:hover:cursor-pointer focus:border-input focus:ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm",\n });\n</script>\n',
|
|
1152
1152
|
},
|
|
1153
1153
|
],
|
|
1154
1154
|
utils: [],
|
|
@@ -1407,7 +1407,7 @@ export default [
|
|
|
1407
1407
|
fileName: "NativeSelect.vue",
|
|
1408
1408
|
dirPath: "components/UI",
|
|
1409
1409
|
fileContent:
|
|
1410
|
-
'<template>\n <div class="relative">\n <select\n :id="id"\n ref="select"\n v-model="localModel"\n :multiple="multiple"\n :name="name"\n :size="size"\n :placeholder="placeholder"\n :disabled="disabled"\n :required="required"\n :class="styles({ class: props.class })"\n >\n <slot />\n </select>\n <span class="pointer-events-none absolute inset-y-0 right-3 flex items-center justify-center">\n <slot name="trailingIcon">\n <Icon\n :name="trailingIcon || \'lucide:chevrons-up-down\'"\n class="h-4 w-4 text-muted-foreground"\n />\n </slot>\n </span>\n </div>\n</template>\n\n<script lang="ts" setup>\n const props = defineProps<{\n class?: any;\n id?: string;\n name?: string;\n placeholder?: string;\n disabled?: boolean;\n required?: boolean;\n modelValue?: any;\n multiple?: boolean;\n size?: number;\n autofocus?: boolean;\n trailingIcon?: string;\n }>();\n const styles = tv({\n base: "h-10 w-full appearance-none rounded-md border border-input bg-background px-3 py-2 pr-10 ring-offset-background focus-visible:outline-none
|
|
1410
|
+
'<template>\n <div class="relative">\n <select\n :id="id"\n ref="select"\n v-model="localModel"\n :multiple="multiple"\n :name="name"\n :size="size"\n :placeholder="placeholder"\n :disabled="disabled"\n :required="required"\n :class="styles({ class: props.class })"\n >\n <slot />\n </select>\n <span class="pointer-events-none absolute inset-y-0 right-3 flex items-center justify-center">\n <slot name="trailingIcon">\n <Icon\n :name="trailingIcon || \'lucide:chevrons-up-down\'"\n class="h-4 w-4 text-muted-foreground"\n />\n </slot>\n </span>\n </div>\n</template>\n\n<script lang="ts" setup>\n const props = defineProps<{\n class?: any;\n id?: string;\n name?: string;\n placeholder?: string;\n disabled?: boolean;\n required?: boolean;\n modelValue?: any;\n multiple?: boolean;\n size?: number;\n autofocus?: boolean;\n trailingIcon?: string;\n }>();\n const styles = tv({\n base: "h-10 w-full appearance-none rounded-md border border-input bg-background px-3 py-2 pr-10 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm",\n });\n\n const select = ref<HTMLSelectElement | null>(null);\n const emits = defineEmits<{\n "update:modelValue": [value: any];\n }>();\n\n const localModel = useVModel(props, "modelValue", emits);\n\n onMounted(() => {\n if (props.autofocus) {\n select.value?.focus();\n }\n });\n</script>\n',
|
|
1411
1411
|
},
|
|
1412
1412
|
],
|
|
1413
1413
|
utils: [],
|
|
@@ -1492,6 +1492,40 @@ export default [
|
|
|
1492
1492
|
composables: [],
|
|
1493
1493
|
plugins: [],
|
|
1494
1494
|
},
|
|
1495
|
+
{
|
|
1496
|
+
name: "Number Field",
|
|
1497
|
+
value: "number-field",
|
|
1498
|
+
deps: ["@internationalized/number"],
|
|
1499
|
+
files: [
|
|
1500
|
+
{
|
|
1501
|
+
fileName: "NumberField/Decrement.vue",
|
|
1502
|
+
dirPath: "components/UI",
|
|
1503
|
+
fileContent:
|
|
1504
|
+
'<template>\n <NumberFieldDecrement v-bind="forwarded" :class="styles({ class: props.class })">\n <slot>\n <Icon :name="props.icon" />\n </slot>\n </NumberFieldDecrement>\n</template>\n\n<script lang="ts" setup>\n import { NumberFieldDecrement, useForwardProps } from "radix-vue";\n import type { NumberFieldDecrementProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n NumberFieldDecrementProps & {\n class?: any;\n icon?: string;\n }\n >(),\n { icon: "lucide:minus" }\n );\n\n const forwarded = useForwardProps(reactiveOmit(props, "class"));\n\n const styles = tv({\n base: "flex h-full shrink-0 items-center justify-center bg-transparent p-3 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50",\n });\n</script>\n',
|
|
1505
|
+
},
|
|
1506
|
+
{
|
|
1507
|
+
fileName: "NumberField/Increment.vue",
|
|
1508
|
+
dirPath: "components/UI",
|
|
1509
|
+
fileContent:
|
|
1510
|
+
'<template>\n <NumberFieldIncrement v-bind="forwarded" :class="styles({ class: props.class })">\n <slot>\n <Icon :name="props.icon" />\n </slot>\n </NumberFieldIncrement>\n</template>\n\n<script lang="ts" setup>\n import { NumberFieldIncrement, useForwardProps } from "radix-vue";\n import type { NumberFieldIncrementProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n NumberFieldIncrementProps & {\n class?: any;\n icon?: string;\n }\n >(),\n { icon: "lucide:plus" }\n );\n\n const forwarded = useForwardProps(reactiveOmit(props, "class"));\n\n const styles = tv({\n base: "flex h-full shrink-0 items-center justify-center bg-transparent p-3 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50",\n });\n</script>\n',
|
|
1511
|
+
},
|
|
1512
|
+
{
|
|
1513
|
+
fileName: "NumberField/Input.vue",
|
|
1514
|
+
dirPath: "components/UI",
|
|
1515
|
+
fileContent:
|
|
1516
|
+
'<template>\n <NumberFieldInput v-bind="forwarded" :class="styles({ class: props.class })" />\n</template>\n\n<script lang="ts" setup>\n import { NumberFieldInput, useForwardProps } from "radix-vue";\n import type { NumberFieldInputProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n NumberFieldInputProps & {\n class?: any;\n }\n >(),\n {}\n );\n\n const forwarded = useForwardProps(reactiveOmit(props, "class"));\n\n const styles = tv({\n base: "h-full w-full grow bg-transparent text-center text-base placeholder:text-muted-foreground/80 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm",\n });\n</script>\n',
|
|
1517
|
+
},
|
|
1518
|
+
{
|
|
1519
|
+
fileName: "NumberField/NumberField.vue",
|
|
1520
|
+
dirPath: "components/UI",
|
|
1521
|
+
fileContent:
|
|
1522
|
+
'<template>\n <NumberFieldRoot\n v-slot="rootSlotProps"\n v-bind="forwarded"\n :class="styles({ class: props.class })"\n >\n <slot v-bind="rootSlotProps">\n <slot name="decrement">\n <UiNumberFieldDecrement />\n </slot>\n <slot name="input">\n <UiNumberFieldInput />\n </slot>\n <slot name="increment">\n <UiNumberFieldIncrement />\n </slot>\n </slot>\n </NumberFieldRoot>\n</template>\n\n<script lang="ts" setup>\n import { NumberFieldRoot, useForwardPropsEmits } from "radix-vue";\n import type { NumberFieldRootEmits, NumberFieldRootProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n NumberFieldRootProps & {\n class?: any;\n }\n >(),\n {}\n );\n\n const emit = defineEmits<NumberFieldRootEmits>();\n const forwarded = useForwardPropsEmits(reactiveOmit(props, "class"), emit);\n\n const styles = tv({\n base: "flex h-10 w-full items-center gap-1 rounded-md border border-input bg-background text-base focus-within:border-input focus-within:outline-none focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm",\n });\n</script>\n',
|
|
1523
|
+
},
|
|
1524
|
+
],
|
|
1525
|
+
utils: [],
|
|
1526
|
+
composables: [],
|
|
1527
|
+
plugins: [],
|
|
1528
|
+
},
|
|
1495
1529
|
{
|
|
1496
1530
|
name: "Pagination",
|
|
1497
1531
|
value: "pagination",
|
|
@@ -1848,7 +1882,7 @@ export default [
|
|
|
1848
1882
|
fileName: "Sheet/Content.vue",
|
|
1849
1883
|
dirPath: "components/UI",
|
|
1850
1884
|
fileContent:
|
|
1851
|
-
'<template>\n <UiSheetPortal :to="to">\n <slot name="overlay">\n <UiSheetOverlay />\n </slot>\n <DialogContent\n :class="styles({ side, class: props.class })"\n v-bind="{ ...forwarded, ...$attrs }"\n >\n <slot>\n <slot name="header">\n <UiSheetHeader>\n <slot name="title">\n <UiSheetTitle v-if="title" :title="title" />\n </slot>\n <slot name="description">\n <UiSheetDescription v-if="description" :description="description" />\n </slot>\n </UiSheetHeader>\n </slot>\n <slot name="content" />\n <slot name="footer" />\n </slot>\n <slot name="close">\n <UiSheetClose :icon="icon" />\n </slot>\n </DialogContent>\n </UiSheetPortal>\n</template>\n\n<script lang="ts" setup>\n import { DialogContent, useForwardPropsEmits } from "radix-vue";\n import type { DialogContentEmits, DialogContentProps } from "radix-vue";\n\n defineOptions({ inheritAttrs: false });\n\n const props = defineProps<\n DialogContentProps & {\n icon?: string;\n title?: string;\n description?: string;\n class?: any;\n side?: VariantProps<typeof styles>["side"];\n to?: string | HTMLElement;\n }\n >();\n const emits = defineEmits<DialogContentEmits>();\n const forwarded = useForwardPropsEmits(\n reactiveOmit(props, "icon", "title", "description", "class", "to", "side"),\n emits\n );\n\n const styles = tv({\n base: "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out",\n variants: {\n side: {\n top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",\n bottom:\n "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",\n left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",\n right:\n "inset-y-0 right-0 h-full w-3/4
|
|
1885
|
+
'<template>\n <UiSheetPortal :to="to">\n <slot name="overlay">\n <UiSheetOverlay />\n </slot>\n <DialogContent\n :class="styles({ side, class: props.class })"\n v-bind="{ ...forwarded, ...$attrs }"\n >\n <slot>\n <slot name="header">\n <UiSheetHeader>\n <slot name="title">\n <UiSheetTitle v-if="title" :title="title" />\n </slot>\n <slot name="description">\n <UiSheetDescription v-if="description" :description="description" />\n </slot>\n </UiSheetHeader>\n </slot>\n <slot name="content" />\n <slot name="footer" />\n </slot>\n <slot name="close">\n <UiSheetClose :icon="icon" />\n </slot>\n </DialogContent>\n </UiSheetPortal>\n</template>\n\n<script lang="ts" setup>\n import { DialogContent, useForwardPropsEmits } from "radix-vue";\n import type { DialogContentEmits, DialogContentProps } from "radix-vue";\n\n defineOptions({ inheritAttrs: false });\n\n const props = defineProps<\n DialogContentProps & {\n icon?: string;\n title?: string;\n description?: string;\n class?: any;\n side?: VariantProps<typeof styles>["side"];\n to?: string | HTMLElement;\n }\n >();\n const emits = defineEmits<DialogContentEmits>();\n const forwarded = useForwardPropsEmits(\n reactiveOmit(props, "icon", "title", "description", "class", "to", "side"),\n emits\n );\n\n const styles = tv({\n base: "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out",\n variants: {\n side: {\n top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",\n bottom:\n "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",\n left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",\n right:\n "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",\n },\n },\n defaultVariants: {\n side: "left",\n },\n });\n</script>\n',
|
|
1852
1886
|
},
|
|
1853
1887
|
{
|
|
1854
1888
|
fileName: "Sheet/Description.vue",
|
|
@@ -2088,7 +2122,7 @@ export default [
|
|
|
2088
2122
|
fileName: "Tabs/List.vue",
|
|
2089
2123
|
dirPath: "components/UI",
|
|
2090
2124
|
fileContent:
|
|
2091
|
-
'<template>\n <TabsList :class="styles({ pill, class: props.class })" v-bind="reactiveOmit(props, \'class\')">\n <slot />\n </TabsList>\n</template>\n\n<script lang="ts" setup>\n import { TabsList } from "radix-vue";\n import type { TabsListProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n TabsListProps & {\n /** Custom class(es) to add to parent element */\n class?: any;\n pill?: boolean;\n }\n >(),\n { pill: true }\n );\n\n const styles = tv({\n base: "inline-flex h-10 items-center justify-center rounded-md
|
|
2125
|
+
'<template>\n <TabsList :class="styles({ pill, class: props.class })" v-bind="reactiveOmit(props, \'class\')">\n <slot />\n </TabsList>\n</template>\n\n<script lang="ts" setup>\n import { TabsList } from "radix-vue";\n import type { TabsListProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n TabsListProps & {\n /** Custom class(es) to add to parent element */\n class?: any;\n pill?: boolean;\n }\n >(),\n { pill: true }\n );\n\n const styles = tv({\n base: "inline-flex h-10 items-center justify-center rounded-md p-1 text-muted-foreground",\n variants: {\n pill: {\n true: "bg-muted",\n false: "",\n },\n },\n });\n</script>\n',
|
|
2092
2126
|
},
|
|
2093
2127
|
{
|
|
2094
2128
|
fileName: "Tabs/Tabs.vue",
|
|
@@ -2100,7 +2134,7 @@ export default [
|
|
|
2100
2134
|
fileName: "Tabs/Trigger.vue",
|
|
2101
2135
|
dirPath: "components/UI",
|
|
2102
2136
|
fileContent:
|
|
2103
|
-
'<template>\n <TabsTrigger v-bind="reactiveOmit(props, \'class\')" :class="styles({ pill, class: props.class })">\n <slot />\n </TabsTrigger>\n</template>\n\n<script lang="ts" setup>\n import { TabsTrigger } from "radix-vue";\n import type { TabsTriggerProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n TabsTriggerProps & {\n /** Custom class(es) to add to parent element */\n class?: any;\n /** Whether the trigger should be pill-shaped */\n pill?: boolean;\n }\n >(),\n {\n pill: true,\n }\n );\n\n const styles = tv({\n base: "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50
|
|
2137
|
+
'<template>\n <TabsTrigger v-bind="reactiveOmit(props, \'class\')" :class="styles({ pill, class: props.class })">\n <slot />\n </TabsTrigger>\n</template>\n\n<script lang="ts" setup>\n import { TabsTrigger } from "radix-vue";\n import type { TabsTriggerProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n TabsTriggerProps & {\n /** Custom class(es) to add to parent element */\n class?: any;\n /** Whether the trigger should be pill-shaped */\n pill?: boolean;\n }\n >(),\n {\n pill: true,\n }\n );\n\n const styles = tv({\n base: "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",\n variants: {\n pill: {\n true: "data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",\n false:\n "data-[state=active]:bg-transparent data-[state=active]:text-foreground data-[state=active]:shadow-none",\n },\n },\n });\n</script>\n',
|
|
2104
2138
|
},
|
|
2105
2139
|
],
|
|
2106
2140
|
utils: [],
|
|
@@ -2202,13 +2236,13 @@ export default [
|
|
|
2202
2236
|
fileName: "Toast/Action.vue",
|
|
2203
2237
|
dirPath: "components/UI",
|
|
2204
2238
|
fileContent:
|
|
2205
|
-
'<template>\n <ToastAction :class="styles({ class: props.class })" v-bind="reactiveOmit(props, \'class\')">\n <slot />\n </ToastAction>\n</template>\n\n<script lang="ts" setup>\n import { ToastAction } from "radix-vue";\n import type { ToastActionProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n ToastActionProps & {\n /**\n * Custom class names to add to the button.\n */\n class?: any;\n }\n >(),\n {\n altText: "Action button",\n }\n );\n\n const styles = tv({\n base: "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3
|
|
2239
|
+
'<template>\n <ToastAction :class="styles({ class: props.class })" v-bind="reactiveOmit(props, \'class\')">\n <slot />\n </ToastAction>\n</template>\n\n<script lang="ts" setup>\n import { ToastAction } from "radix-vue";\n import type { ToastActionProps } from "radix-vue";\n\n const props = withDefaults(\n defineProps<\n ToastActionProps & {\n /**\n * Custom class names to add to the button.\n */\n class?: any;\n }\n >(),\n {\n altText: "Action button",\n }\n );\n\n const styles = tv({\n base: "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-xs font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",\n });\n</script>\n',
|
|
2206
2240
|
},
|
|
2207
2241
|
{
|
|
2208
2242
|
fileName: "Toast/Close.vue",
|
|
2209
2243
|
dirPath: "components/UI",
|
|
2210
2244
|
fileContent:
|
|
2211
|
-
'<template>\n <ToastClose :class="styles({ class: props.class })" v-bind="reactiveOmit(props, \'class\', \'icon\')">\n <slot>\n <Icon :name="icon || \'lucide:x\'" class="h-4 w-4" />\n </slot>\n </ToastClose>\n</template>\n\n<script lang="ts" setup>\n import { ToastClose } from "radix-vue";\n import type { ToastCloseProps } from "radix-vue";\n\n const props = defineProps<\n ToastCloseProps & {\n /**\n * Custom class names to add to the button.\n */\n class?: any;\n /**\n * The icon to render.\n */\n icon?: string;\n }\n >();\n\n const styles = tv({\n base: "absolute right-2 top-2 inline-flex items-center justify-center rounded-md p-1 text-foreground/50 opacity-50 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 focus-visible:ring-ring
|
|
2245
|
+
'<template>\n <ToastClose :class="styles({ class: props.class })" v-bind="reactiveOmit(props, \'class\', \'icon\')">\n <slot>\n <Icon :name="icon || \'lucide:x\'" class="h-4 w-4" />\n </slot>\n </ToastClose>\n</template>\n\n<script lang="ts" setup>\n import { ToastClose } from "radix-vue";\n import type { ToastCloseProps } from "radix-vue";\n\n const props = defineProps<\n ToastCloseProps & {\n /**\n * Custom class names to add to the button.\n */\n class?: any;\n /**\n * The icon to render.\n */\n icon?: string;\n }\n >();\n\n const styles = tv({\n base: "absolute right-2 top-2 inline-flex items-center justify-center rounded-md p-1 text-foreground/50 opacity-50 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 focus-visible:ring-ring group-hover:opacity-100",\n });\n</script>\n',
|
|
2212
2246
|
},
|
|
2213
2247
|
{
|
|
2214
2248
|
fileName: "Toast/Description.vue",
|
|
@@ -2244,7 +2278,7 @@ export default [
|
|
|
2244
2278
|
fileName: "Toast/Viewport.vue",
|
|
2245
2279
|
dirPath: "components/UI",
|
|
2246
2280
|
fileContent:
|
|
2247
|
-
'<template>\n <ToastViewport :class="styles({ class: props.class })" v-bind="reactiveOmit(props, \'class\')">\n <slot />\n </ToastViewport>\n</template>\n\n<script lang="ts" setup>\n import { ToastViewport } from "radix-vue";\n import type { ToastViewportProps } from "radix-vue";\n\n const props = defineProps<\n ToastViewportProps & {\n /**\n * Custom class names to add to the button.\n */\n class?: any;\n }\n >();\n\n const styles = tv({\n base: "fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse gap-2 p-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring
|
|
2281
|
+
'<template>\n <ToastViewport :class="styles({ class: props.class })" v-bind="reactiveOmit(props, \'class\')">\n <slot />\n </ToastViewport>\n</template>\n\n<script lang="ts" setup>\n import { ToastViewport } from "radix-vue";\n import type { ToastViewportProps } from "radix-vue";\n\n const props = defineProps<\n ToastViewportProps & {\n /**\n * Custom class names to add to the button.\n */\n class?: any;\n }\n >();\n\n const styles = tv({\n base: "fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse gap-2 p-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring sm:bottom-auto sm:right-0 sm:flex-col md:max-w-[420px]",\n });\n</script>\n\n<style>\n [aria-label~="Notifications"] {\n display: grid;\n }\n</style>\n',
|
|
2248
2282
|
},
|
|
2249
2283
|
],
|
|
2250
2284
|
utils: [],
|
|
@@ -2331,6 +2365,33 @@ export default [
|
|
|
2331
2365
|
composables: [],
|
|
2332
2366
|
plugins: [],
|
|
2333
2367
|
},
|
|
2368
|
+
{
|
|
2369
|
+
name: "Tree",
|
|
2370
|
+
value: "tree",
|
|
2371
|
+
files: [
|
|
2372
|
+
{
|
|
2373
|
+
fileName: "Tree/Item.vue",
|
|
2374
|
+
dirPath: "components/UI",
|
|
2375
|
+
fileContent:
|
|
2376
|
+
'<template>\n <TreeItem v-slot="slotProps" v-bind="forwarded">\n <slot v-bind="slotProps" />\n </TreeItem>\n</template>\n\n<script lang="ts" setup generic="T extends Record<string, any>">\n import { TreeItem, useForwardPropsEmits } from "radix-vue";\n import type { TreeItemProps } from "radix-vue";\n\n // Remove this when the type is properly exported from radix-vue\n type TreeItemEmits = {\n /**\n * Event handler called when the selecting item.\n *\n * It can be prevented by calling `event.preventDefault`.\n */\n select: [event: any];\n /**\n * Event handler called when the selecting item.\n *\n * It can be prevented by calling `event.preventDefault`.\n */\n toggle: [event: any];\n };\n\n const props = defineProps<TreeItemProps<T>>();\n\n const emit = defineEmits<TreeItemEmits>();\n\n const forwarded = useForwardPropsEmits(props, emit);\n</script>\n',
|
|
2377
|
+
},
|
|
2378
|
+
{
|
|
2379
|
+
fileName: "Tree/Tree.vue",
|
|
2380
|
+
dirPath: "components/UI",
|
|
2381
|
+
fileContent:
|
|
2382
|
+
'<template>\n <TreeRoot v-slot="slotProps" v-bind="forwarded">\n <slot v-bind="slotProps" />\n </TreeRoot>\n</template>\n\n<script lang="ts" setup>\n import { TreeRoot, useForwardPropsEmits } from "radix-vue";\n import type { TreeRootEmits, TreeRootProps } from "radix-vue";\n\n const props = defineProps<TreeRootProps>();\n const emit = defineEmits<TreeRootEmits>();\n\n const forwarded = useForwardPropsEmits(props, emit);\n</script>\n',
|
|
2383
|
+
},
|
|
2384
|
+
{
|
|
2385
|
+
fileName: "Tree/Virtualizer.vue",
|
|
2386
|
+
dirPath: "components/UI",
|
|
2387
|
+
fileContent:
|
|
2388
|
+
'<template>\n <TreeVirtualizer v-slot="slotProps" v-bind="forwarded">\n <slot v-bind="slotProps" />\n </TreeVirtualizer>\n</template>\n\n<script lang="ts" setup>\n import { TreeVirtualizer, useForwardPropsEmits } from "radix-vue";\n import type { TreeVirtualizerProps } from "radix-vue";\n\n const props = defineProps<TreeVirtualizerProps>();\n\n const forwarded = useForwardPropsEmits(props);\n</script>\n',
|
|
2389
|
+
},
|
|
2390
|
+
],
|
|
2391
|
+
utils: [],
|
|
2392
|
+
composables: [],
|
|
2393
|
+
plugins: [],
|
|
2394
|
+
},
|
|
2334
2395
|
{
|
|
2335
2396
|
name: "VeeCheckbox",
|
|
2336
2397
|
value: "vee-checkbox",
|
|
@@ -2464,6 +2525,25 @@ export default [
|
|
|
2464
2525
|
composables: [],
|
|
2465
2526
|
plugins: [],
|
|
2466
2527
|
},
|
|
2528
|
+
{
|
|
2529
|
+
name: "VeeNumberField",
|
|
2530
|
+
value: "vee-number-field",
|
|
2531
|
+
deps: ["@vee-validate/nuxt", "@morev/vue-transitions", "@internationalized/number"],
|
|
2532
|
+
askValidator: true,
|
|
2533
|
+
nuxtModules: ["@vee-validate/nuxt", "@morev/vue-transitions/nuxt"],
|
|
2534
|
+
components: ["label", "number-field"],
|
|
2535
|
+
files: [
|
|
2536
|
+
{
|
|
2537
|
+
fileName: "Vee/NumberField.vue",
|
|
2538
|
+
dirPath: "components/UI",
|
|
2539
|
+
fileContent:
|
|
2540
|
+
'<template>\n <div class="w-full">\n <UiLabel\n v-if="label"\n :for="inputId"\n :hint="labelHint"\n :class="[disabled && \'text-muted-foreground\', errorMessage && \'text-destructive\', \'mb-2\']"\n ><span>{{ label }} <span v-if="required" class="text-destructive">*</span></span></UiLabel\n >\n <div class="relative">\n <UiNumberField\n v-bind="($attrs, props)"\n :id="inputId"\n v-model="value"\n :disabled="disabled"\n :required="required"\n :name="name"\n >\n <template v-for="(_, slotName) in $slots" #[slotName]="scope">\n <slot :name="slotName" v-bind="scope" />\n </template>\n </UiNumberField>\n </div>\n <TransitionSlide group tag="div">\n <p v-if="hint && !errorMessage" key="hint" class="mt-1.5 text-sm text-muted-foreground">\n {{ hint }}\n </p>\n\n <p v-if="errorMessage" key="errorMessage" class="mt-1.5 text-sm text-destructive">\n {{ errorMessage }}\n </p>\n </TransitionSlide>\n </div>\n</template>\n\n<script lang="ts" setup>\n import type { NumberFieldRootProps } from "radix-vue";\n\n interface Props extends NumberFieldRootProps {\n label?: string;\n labelHint?: string;\n hint?: string;\n disabled?: boolean;\n name?: string;\n id?: string;\n rules?: any;\n validateOnMount?: boolean;\n required?: boolean;\n }\n const props = defineProps<Props>();\n\n const inputId = computed(() => props.id || useId());\n\n const { errorMessage, value } = useField(() => props.name || inputId.value, props.rules, {\n initialValue: props.modelValue,\n label: props.label,\n validateOnMount: props.validateOnMount,\n syncVModel: true,\n });\n</script>\n',
|
|
2541
|
+
},
|
|
2542
|
+
],
|
|
2543
|
+
utils: [],
|
|
2544
|
+
composables: [],
|
|
2545
|
+
plugins: [],
|
|
2546
|
+
},
|
|
2467
2547
|
{
|
|
2468
2548
|
name: "Vee Pin Input",
|
|
2469
2549
|
value: "vee-pin-input",
|
package/src/types.ts
CHANGED
package/src/utils/config.ts
CHANGED
|
@@ -18,6 +18,7 @@ const defaultConfig = {
|
|
|
18
18
|
tailwindConfigLocation: "tailwind.config.js",
|
|
19
19
|
componentsLocation: "components/Ui",
|
|
20
20
|
composablesLocation: "composables",
|
|
21
|
+
pluginsLocation: "plugins",
|
|
21
22
|
utilsLocation: "utils",
|
|
22
23
|
force: true,
|
|
23
24
|
useDefaultFilename: true,
|
|
@@ -81,6 +82,7 @@ export const getUIConfig = async (options?: InitOptions) => {
|
|
|
81
82
|
export const createConfigPaths = (uiConfig: UIConfig) => {
|
|
82
83
|
// Esnure files exists
|
|
83
84
|
if (uiConfig.tailwindCSSLocation) fse.ensureFileSync(uiConfig.tailwindConfigLocation);
|
|
85
|
+
if (uiConfig.pluginsLocation) fse.ensureDirSync(uiConfig.pluginsLocation);
|
|
84
86
|
if (uiConfig.tailwindConfigLocation) fse.ensureFileSync(uiConfig.tailwindCSSLocation);
|
|
85
87
|
if (uiConfig.componentsLocation) fse.ensureDirSync(uiConfig.componentsLocation);
|
|
86
88
|
if (uiConfig.composablesLocation) fse.ensureDirSync(uiConfig.composablesLocation);
|
|
@@ -35,6 +35,12 @@ export const initPrompts = async () => {
|
|
|
35
35
|
message: "Where should your composables be stored?",
|
|
36
36
|
initial: "composables",
|
|
37
37
|
},
|
|
38
|
+
{
|
|
39
|
+
name: "pluginsLocation",
|
|
40
|
+
type: "text",
|
|
41
|
+
message: "Where should your plugins be stored?",
|
|
42
|
+
initial: "plugins",
|
|
43
|
+
},
|
|
38
44
|
{
|
|
39
45
|
name: "utilsLocation",
|
|
40
46
|
type: "text",
|