pukaad-ui-lib 1.19.0 → 1.22.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.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
3
  "configKey": "pukaadUI",
4
- "version": "1.19.0",
4
+ "version": "1.22.2",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -4,6 +4,7 @@ interface TypeItem {
4
4
  }
5
5
  type __VLS_Props = {
6
6
  items?: TypeItem[];
7
+ divider?: boolean;
7
8
  };
8
9
  declare var __VLS_6: {
9
10
  label: string;
@@ -23,6 +24,7 @@ type __VLS_Slots = {} & {
23
24
  };
24
25
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
25
26
  items: TypeItem[];
27
+ divider: boolean;
26
28
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
27
29
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
28
30
  declare const _default: typeof __VLS_export;
@@ -22,17 +22,29 @@
22
22
  </div>
23
23
  </div>
24
24
  <div class="flex flex-col w-full mb-[16px]">
25
- <div :ref="(el) => {
26
- labelRef[i_item] = el;
27
- }">
28
- <slot name="title" :label="item.label" :item="item" />
25
+ <div
26
+ :ref="
27
+ (el) => {
28
+ labelRef[i_item] = el;
29
+ }
30
+ "
31
+ >
32
+ <div :class="divider ? 'border-b border-silver w-full' : 'w-full'">
33
+ <slot name="title" :label="item.label" :item="item" />
34
+ </div>
29
35
  </div>
30
36
  <div
31
37
  v-if="arrShow.includes(i_item)"
32
- class="flex flex-col gap-[16px] mt-[16px] pl-[32px]"
38
+ class="flex flex-col gap-[16px] mt-[16px]"
33
39
  >
34
40
  <slot name="children" :items="item.children">
35
- <div v-for="(cill, i_child) in item.children" :key="i_child">
41
+ <div
42
+ v-for="(cill, i_child) in item.children"
43
+ :key="i_child"
44
+ :class="
45
+ divider ? 'border-b border-silver pl-[24px]' : 'pl-[24px]'
46
+ "
47
+ >
36
48
  <slot name="children-item" :label="cill.label" :item="cill" />
37
49
  </div>
38
50
  </slot>
@@ -46,7 +58,8 @@
46
58
  <script setup>
47
59
  import { ref } from "vue";
48
60
  const props = defineProps({
49
- items: { type: Array, required: false, default: () => [] }
61
+ items: { type: Array, required: false, default: () => [] },
62
+ divider: { type: Boolean, required: false, default: () => false }
50
63
  });
51
64
  const labelRef = ref([]);
52
65
  const arrShow = ref([]);
@@ -4,6 +4,7 @@ interface TypeItem {
4
4
  }
5
5
  type __VLS_Props = {
6
6
  items?: TypeItem[];
7
+ divider?: boolean;
7
8
  };
8
9
  declare var __VLS_6: {
9
10
  label: string;
@@ -23,6 +24,7 @@ type __VLS_Slots = {} & {
23
24
  };
24
25
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
25
26
  items: TypeItem[];
27
+ divider: boolean;
26
28
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
27
29
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
28
30
  declare const _default: typeof __VLS_export;
@@ -36,9 +36,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
36
36
  id: string;
37
37
  name: string;
38
38
  description: string;
39
- limit: number;
40
- placeholder: string;
41
39
  options: AutocompleteOption[] | string[] | number[];
40
+ placeholder: string;
41
+ limit: number;
42
42
  disabledErrorMessage: boolean;
43
43
  disabledBorder: boolean;
44
44
  showCounter: boolean;
@@ -36,9 +36,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
36
36
  id: string;
37
37
  name: string;
38
38
  description: string;
39
- limit: number;
40
- placeholder: string;
41
39
  options: AutocompleteOption[] | string[] | number[];
40
+ placeholder: string;
41
+ limit: number;
42
42
  disabledErrorMessage: boolean;
43
43
  disabledBorder: boolean;
44
44
  showCounter: boolean;
@@ -1,44 +1,57 @@
1
- import type { InputTextareaProps } from "@/types/components/input/input-textarea";
1
+ export interface InputTextareaProps {
2
+ id?: string;
3
+ name?: string;
4
+ disabled?: boolean;
5
+ label?: string;
6
+ rules?: object | string | Function;
7
+ readonly?: boolean;
8
+ placeholder?: string;
9
+ description?: string;
10
+ disabledErrorMessage?: boolean;
11
+ disabledBorder?: boolean;
12
+ required?: boolean;
13
+ showCounter?: boolean;
14
+ limit?: number;
15
+ resize?: "none" | "both" | "horizontal" | "vertical";
16
+ rows?: number;
17
+ fullWidth?: boolean;
18
+ fullHeight?: boolean;
19
+ heightScroll?: boolean;
20
+ height?: number;
21
+ width?: number;
22
+ class?: string;
23
+ }
2
24
  type __VLS_Props = InputTextareaProps;
3
25
  type __VLS_ModelProps = {
4
26
  modelValue?: string;
5
27
  };
6
28
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
7
- declare var __VLS_7: {
8
- label: string | undefined;
9
- }, __VLS_9: {};
29
+ declare var __VLS_18: {};
10
30
  type __VLS_Slots = {} & {
11
- label?: (props: typeof __VLS_7) => any;
12
- } & {
13
- error?: (props: typeof __VLS_9) => any;
31
+ label?: (props: typeof __VLS_18) => any;
14
32
  };
15
33
  declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
16
34
  focus: () => void;
35
+ setErrors: (errMsg: string[]) => void;
17
36
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
18
- "update:modelValue": (value: string | undefined) => any;
37
+ "update:modelValue": (value: string) => any;
19
38
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
20
- "onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
39
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
21
40
  }>, {
22
- variant: "default" | "primary" | "error";
23
41
  fullWidth: boolean;
24
42
  fullHeight: boolean;
25
43
  required: boolean;
44
+ id: string;
26
45
  name: string;
27
46
  disabled: boolean;
28
- disabledPadding: boolean;
29
- rows: number | string;
47
+ rows: number;
48
+ limit: number;
30
49
  disabledErrorMessage: boolean;
31
50
  disabledBorder: boolean;
32
51
  showCounter: boolean;
33
52
  resize: "none" | "both" | "horizontal" | "vertical";
34
53
  readonly: boolean;
35
- standalone: boolean;
36
- inputClass: string;
37
- disabledBorderFocus: boolean;
38
54
  heightScroll: boolean;
39
- validateOnBlur: boolean;
40
- validateOnInput: boolean;
41
- maxLength: number;
42
55
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
43
56
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
44
57
  declare const _default: typeof __VLS_export;
@@ -1,132 +1,111 @@
1
1
  <template>
2
- <Field
2
+ <ShadFormField
3
+ ref="fieldRef"
3
4
  :name="props.name"
4
- v-slot="{ field, errorMessage }"
5
- :validate-on-blur="props.validateOnBlur"
6
- :validate-on-input="props.validateOnInput"
7
- :standalone="props.standalone"
8
- :rules="rules || defaultRule"
5
+ :rules="props.rules || defaultRules"
6
+ v-slot="{ componentField }"
9
7
  v-model="modelValue"
10
8
  >
11
- <div class="flex flex-col gap-[4px]">
12
- <slot
13
- v-if="$slots.label || props.label"
14
- name="label"
15
- :label="props.label"
16
- >
17
- <div class="text-gray flex items-center">
18
- <div class="font-body-large-prominent flex-1">
9
+ <ShadFormItem>
10
+ <ShadFormLabel class="w-full">
11
+ <slot name="label">
12
+ <div
13
+ :class="[
14
+ 'flex-1',
15
+ props.disabledBorder && 'font-body-small-prominent'
16
+ ]"
17
+ >
19
18
  {{ props.label }}
20
- <span v-if="props.required" class="text-error">*</span>
19
+ <span v-if="props.required" class="text-destructive">*</span>
21
20
  </div>
22
- <div v-if="props.showCounter" :class="['font-body-small']">
23
- <div
24
- v-if="props.maxLength"
25
- :class="[textCounter > props.maxLength && 'text-error']"
26
- >
27
- {{ textCounter }} / {{ props.maxLength }}
28
- </div>
29
- <div v-else>{{ textCounter }} ตัวอักษร</div>
21
+ </slot>
22
+ <div
23
+ v-if="props.showCounter"
24
+ :class="[props.disabledBorder && 'font-body-small']"
25
+ >
26
+ <div
27
+ v-if="props.limit > 0"
28
+ :class="[modelValue.length > props.limit && 'text-destructive']"
29
+ >
30
+ {{ modelValue.length }}/{{ props.limit }}
30
31
  </div>
32
+ <div v-else>{{ modelValue.length }} ตัวอักษร</div>
31
33
  </div>
32
- </slot>
34
+ </ShadFormLabel>
33
35
 
34
- <textarea
35
- v-bind="field"
36
- ref="textareaRef"
36
+ <ShadInputGroup
37
37
  :class="[
38
- 'w-full bg-white',
39
- 'font-body-large placeholder:text-cloud rounded-[8px] overflow-auto',
40
- props.inputClass,
41
- errorMessage && !props.disabled ? ' focus:ring-error' : borderFocus,
42
- errorMessage && !props.disabled ? 'ring-[1px] ring-error' : variaint,
43
- padding
38
+ props.disabledBorder && 'border-0 ring-0 focus-within:border-0 focus-within:ring-0'
44
39
  ]"
45
- :placeholder="props.placeholder"
46
- :disabled="props.disabled"
47
- :style="{
40
+ >
41
+ <ShadFormControl>
42
+ <ShadInputGroupTextarea
43
+ v-bind="componentField"
44
+ ref="textareaRef"
45
+ :id="props.id || props.name"
46
+ :class="props.class"
47
+ :readonly="props.readonly"
48
+ :disabled="props.disabled"
49
+ :placeholder="props.placeholder"
50
+ :rows="props.rows"
51
+ :style="{
48
52
  resize: props.resize,
49
- height: props.fullHeight ? '100%' : `${props.height}px`,
50
- width: props.fullWidth ? '100%' : `${props.width}px`
53
+ height: props.fullHeight ? '100%' : props.height ? `${props.height}px` : void 0,
54
+ width: props.fullWidth ? '100%' : props.width ? `${props.width}px` : void 0
51
55
  }"
52
- :rows="props.rows"
53
- :readonly="props.readonly"
54
- @input="autoHeight()"
55
- />
56
+ @input="autoHeight()"
57
+ >
58
+ </ShadInputGroupTextarea>
59
+ </ShadFormControl>
60
+ </ShadInputGroup>
56
61
 
57
- <div
58
- v-if="!props.disabledErrorMessage && errorMessage"
59
- class="font-body-small text-error"
60
- >
61
- <slot name="error">
62
- {{ errorMessage }}
63
- </slot>
64
- </div>
65
- </div>
66
- </Field>
62
+ <ShadFormDescription v-if="props.description">
63
+ {{ props.description }}
64
+ </ShadFormDescription>
65
+ <ShadFormMessage v-if="!props.disabledErrorMessage" />
66
+ </ShadFormItem>
67
+ </ShadFormField>
67
68
  </template>
68
69
 
69
70
  <script setup>
70
- import { ref, computed, onMounted } from "vue";
71
+ import { ref, onMounted, nextTick } from "vue";
71
72
  const props = defineProps({
72
- inputClass: { type: String, required: false, default: "" },
73
+ id: { type: String, required: false, default: "input-textarea" },
74
+ name: { type: String, required: false, default: "input-textarea" },
75
+ disabled: { type: Boolean, required: false, default: false },
73
76
  label: { type: String, required: false },
74
- name: { type: String, required: false, default: "text-area" },
75
- placeholder: { type: String, required: false },
76
77
  rules: { type: [Object, String, Function], required: false },
77
- disabled: { type: Boolean, required: false, default: false },
78
+ readonly: { type: Boolean, required: false, default: false },
79
+ placeholder: { type: String, required: false },
80
+ description: { type: String, required: false },
78
81
  disabledErrorMessage: { type: Boolean, required: false, default: false },
79
82
  disabledBorder: { type: Boolean, required: false, default: false },
80
- disabledBorderFocus: { type: Boolean, required: false, default: false },
81
- disabledPadding: { type: Boolean, required: false, default: false },
82
- variant: { type: String, required: false, default: "default" },
83
83
  required: { type: Boolean, required: false, default: false },
84
+ showCounter: { type: Boolean, required: false, default: false },
85
+ limit: { type: Number, required: false, default: 0 },
84
86
  resize: { type: String, required: false, default: "both" },
85
- rows: { type: [Number, String], required: false, default: 4 },
86
- height: { type: [Number, String], required: false },
87
- width: { type: [Number, String], required: false },
87
+ rows: { type: Number, required: false, default: 4 },
88
88
  fullWidth: { type: Boolean, required: false, default: false },
89
89
  fullHeight: { type: Boolean, required: false, default: false },
90
90
  heightScroll: { type: Boolean, required: false, default: true },
91
- standalone: { type: Boolean, required: false, default: false },
92
- validateOnBlur: { type: Boolean, required: false, default: true },
93
- validateOnInput: { type: Boolean, required: false, default: true },
94
- showCounter: { type: Boolean, required: false, default: false },
95
- maxLength: { type: Number, required: false, default: 0 },
96
- readonly: { type: Boolean, required: false, default: false }
91
+ height: { type: Number, required: false },
92
+ width: { type: Number, required: false },
93
+ class: { type: String, required: false }
97
94
  });
98
- const modelValue = defineModel({ type: String });
95
+ const modelValue = defineModel({ type: String, ...{
96
+ default: ""
97
+ } });
98
+ const fieldRef = ref();
99
99
  const textareaRef = ref();
100
- const textCounter = computed(() => modelValue.value?.length || 0);
101
- const defaultRule = (v) => {
102
- if (props.required && v == "") return "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25";
103
- if (props.maxLength > 0 && v && v.length > props.maxLength)
104
- return "\u0E40\u0E01\u0E34\u0E19\u0E08\u0E33\u0E19\u0E27\u0E19\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23\u0E17\u0E35\u0E48\u0E01\u0E33\u0E2B\u0E19\u0E14";
100
+ const defaultRules = (v) => {
101
+ if (!v && props.required) {
102
+ return `\u0E01\u0E23\u0E38\u0E13\u0E32\u0E23\u0E30\u0E1A\u0E38 ${props.label || "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25"}`;
103
+ }
104
+ if (props.limit > 0 && modelValue.value.length > props.limit) {
105
+ return `\u0E08\u0E33\u0E19\u0E27\u0E19\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${props.limit} \u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23`;
106
+ }
105
107
  return true;
106
108
  };
107
- const padding = computed(() => {
108
- if (props.disabledPadding) return;
109
- return "px-[12px] py-[7px]";
110
- });
111
- const borderFocus = computed(() => {
112
- if (props.disabledBorder || props.disabledBorderFocus) return;
113
- const borders = {
114
- default: "focus:ring-[2px] focus:ring-primary",
115
- primary: "focus:ring-[2px] focus:ring-primary",
116
- error: "focus:ring-[2px] focus:ring-error"
117
- };
118
- return borders[props.variant];
119
- });
120
- const variaint = computed(() => {
121
- if (props.disabledBorder) return;
122
- if (props.disabled) return "bg-cloud ring-cloud";
123
- const variants = {
124
- default: "ring-[1px] ring-cloud",
125
- primary: "ring-[1px] ring-primary",
126
- error: "ring-[1px] ring-error"
127
- };
128
- return variants[props.variant];
129
- });
130
109
  const autoHeight = () => {
131
110
  const el = textareaRef.value;
132
111
  if (el) {
@@ -140,10 +119,16 @@ const focus = () => {
140
119
  if (!textareaRef.value) return;
141
120
  textareaRef.value.focus();
142
121
  };
122
+ const setErrors = (errMsg) => {
123
+ fieldRef.value?.setErrors(errMsg);
124
+ };
143
125
  defineExpose({
144
- focus
126
+ focus,
127
+ setErrors
145
128
  });
146
129
  onMounted(() => {
147
- autoHeight();
130
+ nextTick(() => {
131
+ autoHeight();
132
+ });
148
133
  });
149
134
  </script>
@@ -1,44 +1,57 @@
1
- import type { InputTextareaProps } from "@/types/components/input/input-textarea";
1
+ export interface InputTextareaProps {
2
+ id?: string;
3
+ name?: string;
4
+ disabled?: boolean;
5
+ label?: string;
6
+ rules?: object | string | Function;
7
+ readonly?: boolean;
8
+ placeholder?: string;
9
+ description?: string;
10
+ disabledErrorMessage?: boolean;
11
+ disabledBorder?: boolean;
12
+ required?: boolean;
13
+ showCounter?: boolean;
14
+ limit?: number;
15
+ resize?: "none" | "both" | "horizontal" | "vertical";
16
+ rows?: number;
17
+ fullWidth?: boolean;
18
+ fullHeight?: boolean;
19
+ heightScroll?: boolean;
20
+ height?: number;
21
+ width?: number;
22
+ class?: string;
23
+ }
2
24
  type __VLS_Props = InputTextareaProps;
3
25
  type __VLS_ModelProps = {
4
26
  modelValue?: string;
5
27
  };
6
28
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
7
- declare var __VLS_7: {
8
- label: string | undefined;
9
- }, __VLS_9: {};
29
+ declare var __VLS_18: {};
10
30
  type __VLS_Slots = {} & {
11
- label?: (props: typeof __VLS_7) => any;
12
- } & {
13
- error?: (props: typeof __VLS_9) => any;
31
+ label?: (props: typeof __VLS_18) => any;
14
32
  };
15
33
  declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
16
34
  focus: () => void;
35
+ setErrors: (errMsg: string[]) => void;
17
36
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
18
- "update:modelValue": (value: string | undefined) => any;
37
+ "update:modelValue": (value: string) => any;
19
38
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
20
- "onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
39
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
21
40
  }>, {
22
- variant: "default" | "primary" | "error";
23
41
  fullWidth: boolean;
24
42
  fullHeight: boolean;
25
43
  required: boolean;
44
+ id: string;
26
45
  name: string;
27
46
  disabled: boolean;
28
- disabledPadding: boolean;
29
- rows: number | string;
47
+ rows: number;
48
+ limit: number;
30
49
  disabledErrorMessage: boolean;
31
50
  disabledBorder: boolean;
32
51
  showCounter: boolean;
33
52
  resize: "none" | "both" | "horizontal" | "vertical";
34
53
  readonly: boolean;
35
- standalone: boolean;
36
- inputClass: string;
37
- disabledBorderFocus: boolean;
38
54
  heightScroll: boolean;
39
- validateOnBlur: boolean;
40
- validateOnInput: boolean;
41
- maxLength: number;
42
55
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
43
56
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
44
57
  declare const _default: typeof __VLS_export;
@@ -19,6 +19,7 @@ const modelValue = useVModel(props, "modelValue", emits, {
19
19
  data-slot="textarea"
20
20
  :class="
21
21
  cn(
22
+ 'font-body-large',
22
23
  'border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
23
24
  props.class
24
25
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
- "version": "1.19.0",
3
+ "version": "1.22.2",
4
4
  "description": "pukaad-ui for MeMSG",
5
5
  "repository": {
6
6
  "type": "git",
@@ -88,4 +88,4 @@
88
88
  "@types/vue-cropperjs": "^4.1.6",
89
89
  "@vue/compiler-sfc": "^3.5.24"
90
90
  }
91
- }
91
+ }
@@ -1,26 +0,0 @@
1
- type __VLS_ModelProps = {
2
- modelValue?: boolean;
3
- };
4
- declare var __VLS_6: {
5
- open: boolean;
6
- }, __VLS_8: {
7
- open: true;
8
- };
9
- type __VLS_Slots = {} & {
10
- header?: (props: typeof __VLS_6) => any;
11
- } & {
12
- default?: (props: typeof __VLS_8) => any;
13
- };
14
- declare const __VLS_base: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
15
- "update:modelValue": (value: boolean) => any;
16
- }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
17
- "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
18
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
19
- declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
20
- declare const _default: typeof __VLS_export;
21
- export default _default;
22
- type __VLS_WithSlots<T, S> = T & {
23
- new (): {
24
- $slots: S;
25
- };
26
- };
@@ -1,51 +0,0 @@
1
- <template>
2
- <div class="flex flex-col">
3
- <!-- Header Row with Toggle -->
4
- <div class="flex items-center">
5
- <!-- Tree Line + Toggle Button -->
6
- <div
7
- class="relative w-6 shrink-0 mr-4 flex items-center justify-center self-stretch"
8
- >
9
- <!-- Dashed line (full height) -->
10
- <div
11
- class="absolute left-[11px] top-0 bottom-0 w-0 h-full border-l-2 border-dashed border-gray-300"
12
- />
13
-
14
- <!-- Toggle Button (centered with header) -->
15
- <div
16
- class="relative z-10 flex items-center justify-center w-5 h-5 rounded border-2 border-primary text-primary bg-white shrink-0 transition-colors cursor-pointer"
17
- @click.stop="isOpen = !isOpen"
18
- >
19
- <Icon
20
- :name="isOpen ? 'lucide:chevron-down' : 'lucide:chevron-right'"
21
- :size="19"
22
- />
23
- </div>
24
- </div>
25
-
26
- <!-- Header Content -->
27
- <div class="flex-1 min-w-0">
28
- <slot name="header" :open="isOpen" />
29
- </div>
30
- </div>
31
-
32
- <!-- Children (shown when open) -->
33
- <div v-if="isOpen" class="flex">
34
- <!-- Continuation of dashed line -->
35
- <div class="relative w-6 shrink-0 mr-4">
36
- <div
37
- class="absolute left-[11px] top-0 bottom-0 w-0 h-full border-l-2 border-dashed border-gray-300"
38
- />
39
- </div>
40
-
41
- <!-- Children content -->
42
- <div class="flex-1 ml-8 mt-4 flex flex-col gap-4 pb-2">
43
- <slot :open="isOpen" />
44
- </div>
45
- </div>
46
- </div>
47
- </template>
48
-
49
- <script setup>
50
- const isOpen = defineModel({ type: Boolean, ...{ default: false } });
51
- </script>
@@ -1,26 +0,0 @@
1
- type __VLS_ModelProps = {
2
- modelValue?: boolean;
3
- };
4
- declare var __VLS_6: {
5
- open: boolean;
6
- }, __VLS_8: {
7
- open: true;
8
- };
9
- type __VLS_Slots = {} & {
10
- header?: (props: typeof __VLS_6) => any;
11
- } & {
12
- default?: (props: typeof __VLS_8) => any;
13
- };
14
- declare const __VLS_base: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
15
- "update:modelValue": (value: boolean) => any;
16
- }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
17
- "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
18
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
19
- declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
20
- declare const _default: typeof __VLS_export;
21
- export default _default;
22
- type __VLS_WithSlots<T, S> = T & {
23
- new (): {
24
- $slots: S;
25
- };
26
- };