@auronui/vue 1.1.1 → 1.2.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.
Files changed (37) hide show
  1. package/dist/cjs/index.cjs +759 -0
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/composables/useAccordion.js +58 -0
  4. package/dist/composables/useAccordion.js.map +1 -0
  5. package/dist/composables/useCalendar.js +47 -0
  6. package/dist/composables/useCalendar.js.map +1 -0
  7. package/dist/composables/useCheckboxGroup.js +64 -0
  8. package/dist/composables/useCheckboxGroup.js.map +1 -0
  9. package/dist/composables/useColorPicker.js +68 -0
  10. package/dist/composables/useColorPicker.js.map +1 -0
  11. package/dist/composables/useDisclosure.js +43 -0
  12. package/dist/composables/useDisclosure.js.map +1 -0
  13. package/dist/composables/useListBox.js +61 -0
  14. package/dist/composables/useListBox.js.map +1 -0
  15. package/dist/composables/useOTP.js +29 -0
  16. package/dist/composables/useOTP.js.map +1 -0
  17. package/dist/composables/usePagination.js +54 -0
  18. package/dist/composables/usePagination.js.map +1 -0
  19. package/dist/composables/useRadioGroup.js +38 -0
  20. package/dist/composables/useRadioGroup.js.map +1 -0
  21. package/dist/composables/useRangeCalendar.js +51 -0
  22. package/dist/composables/useRangeCalendar.js.map +1 -0
  23. package/dist/composables/useSlider.js +46 -0
  24. package/dist/composables/useSlider.js.map +1 -0
  25. package/dist/composables/useSplitter.js +39 -0
  26. package/dist/composables/useSplitter.js.map +1 -0
  27. package/dist/composables/useStepper.js +58 -0
  28. package/dist/composables/useStepper.js.map +1 -0
  29. package/dist/composables/useSwatchPicker.js +31 -0
  30. package/dist/composables/useSwatchPicker.js.map +1 -0
  31. package/dist/composables/useTabs.js +34 -0
  32. package/dist/composables/useTabs.js.map +1 -0
  33. package/dist/composables/useTree.js +88 -0
  34. package/dist/composables/useTree.js.map +1 -0
  35. package/dist/index.d.ts +786 -64
  36. package/dist/index.js +17 -1
  37. package/package.json +4 -4
@@ -0,0 +1,46 @@
1
+ import { ref } from "vue";
2
+ //#region src/composables/useSlider.ts
3
+ /**
4
+ * Manages value state for the Slider component.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * // Single thumb
9
+ * const slider = useSlider({ defaultValue: 40, min: 0, max: 100 })
10
+ *
11
+ * // Range (two thumbs)
12
+ * const range = useSlider({ defaultValue: [20, 80], min: 0, max: 100 })
13
+ * ```
14
+ * ```html
15
+ * <Slider :model-value="slider.value" :min="slider.min" :max="slider.max" @update:model-value="slider.onValueChange" />
16
+ * ```
17
+ */
18
+ function useSlider(options = {}) {
19
+ const min = options.min ?? 0;
20
+ const max = options.max ?? 100;
21
+ const step = options.step ?? 1;
22
+ const value = ref(options.defaultValue ?? min);
23
+ function clamp(v) {
24
+ if (Array.isArray(v)) return v.map((n) => Math.min(Math.max(n, min), max));
25
+ return Math.min(Math.max(v, min), max);
26
+ }
27
+ function setValue(v) {
28
+ value.value = v;
29
+ }
30
+ function onValueChange(v) {
31
+ value.value = v;
32
+ }
33
+ return {
34
+ value,
35
+ min,
36
+ max,
37
+ step,
38
+ setValue,
39
+ clamp,
40
+ onValueChange
41
+ };
42
+ }
43
+ //#endregion
44
+ export { useSlider };
45
+
46
+ //# sourceMappingURL=useSlider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSlider.js","names":[],"sources":["../../src/composables/useSlider.ts"],"sourcesContent":["import { ref, type Ref } from 'vue'\n\nexport type SliderValue = number | number[]\n\nexport interface UseSliderOptions {\n /** Initial value. Use a number for a single thumb, number[] for range mode. Defaults to `min`. */\n defaultValue?: SliderValue\n /** Minimum allowed value. Defaults to 0. */\n min?: number\n /** Maximum allowed value. Defaults to 100. */\n max?: number\n /** Step increment. Defaults to 1. */\n step?: number\n}\n\nexport interface UseSliderReturn {\n /** Reactive slider value. Number in single mode, number[] in range mode. */\n value: Ref<SliderValue>\n /** Minimum value. */\n min: number\n /** Maximum value. */\n max: number\n /** Step increment. */\n step: number\n /** Set the slider value directly. */\n setValue: (value: SliderValue) => void\n /** Clamp a value (or array of values) to [min, max]. */\n clamp: (value: SliderValue) => SliderValue\n /**\n * Pass as `@update:model-value` handler on the Slider component.\n * Keeps `value` in sync when the component changes internally.\n */\n onValueChange: (value: SliderValue) => void\n}\n\n/**\n * Manages value state for the Slider component.\n *\n * @example\n * ```ts\n * // Single thumb\n * const slider = useSlider({ defaultValue: 40, min: 0, max: 100 })\n *\n * // Range (two thumbs)\n * const range = useSlider({ defaultValue: [20, 80], min: 0, max: 100 })\n * ```\n * ```html\n * <Slider :model-value=\"slider.value\" :min=\"slider.min\" :max=\"slider.max\" @update:model-value=\"slider.onValueChange\" />\n * ```\n */\nexport function useSlider(options: UseSliderOptions = {}): UseSliderReturn {\n const min = options.min ?? 0\n const max = options.max ?? 100\n const step = options.step ?? 1\n\n const value = ref<SliderValue>(options.defaultValue ?? min)\n\n function clamp(v: SliderValue): SliderValue {\n if (Array.isArray(v)) return v.map(n => Math.min(Math.max(n, min), max))\n return Math.min(Math.max(v, min), max)\n }\n\n function setValue(v: SliderValue): void {\n value.value = v\n }\n\n function onValueChange(v: SliderValue): void {\n value.value = v\n }\n\n return {\n value,\n min,\n max,\n step,\n setValue,\n clamp,\n onValueChange,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAkDA,SAAgB,UAAU,UAA4B,EAAE,EAAmB;CACzE,MAAM,MAAM,QAAQ,OAAO;CAC3B,MAAM,MAAM,QAAQ,OAAO;CAC3B,MAAM,OAAO,QAAQ,QAAQ;CAE7B,MAAM,QAAQ,IAAiB,QAAQ,gBAAgB,IAAI;CAE3D,SAAS,MAAM,GAA6B;AAC1C,MAAI,MAAM,QAAQ,EAAE,CAAE,QAAO,EAAE,KAAI,MAAK,KAAK,IAAI,KAAK,IAAI,GAAG,IAAI,EAAE,IAAI,CAAC;AACxE,SAAO,KAAK,IAAI,KAAK,IAAI,GAAG,IAAI,EAAE,IAAI;;CAGxC,SAAS,SAAS,GAAsB;AACtC,QAAM,QAAQ;;CAGhB,SAAS,cAAc,GAAsB;AAC3C,QAAM,QAAQ;;AAGhB,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACD"}
@@ -0,0 +1,39 @@
1
+ import { ref } from "vue";
2
+ //#region src/composables/useSplitter.ts
3
+ /**
4
+ * Tracks panel layout state for the SplitterGroup component.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const splitter = useSplitter({ defaultSizes: [30, 70] })
9
+ * ```
10
+ * ```html
11
+ * <SplitterGroup @layout="splitter.onLayout">
12
+ * <SplitterPanel :default-size="splitter.sizes[0] ?? 30" />
13
+ * <SplitterResizeHandle />
14
+ * <SplitterPanel :default-size="splitter.sizes[1] ?? 70" />
15
+ * </SplitterGroup>
16
+ * ```
17
+ */
18
+ function useSplitter(options = {}) {
19
+ const sizes = ref(options.defaultSizes ? [...options.defaultSizes] : []);
20
+ function setSizes(next) {
21
+ sizes.value = [...next];
22
+ }
23
+ function resetSizes() {
24
+ sizes.value = options.defaultSizes ? [...options.defaultSizes] : [];
25
+ }
26
+ function onLayout(next) {
27
+ sizes.value = next;
28
+ }
29
+ return {
30
+ sizes,
31
+ setSizes,
32
+ resetSizes,
33
+ onLayout
34
+ };
35
+ }
36
+ //#endregion
37
+ export { useSplitter };
38
+
39
+ //# sourceMappingURL=useSplitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSplitter.js","names":[],"sources":["../../src/composables/useSplitter.ts"],"sourcesContent":["import { ref, type Ref } from 'vue'\n\nexport interface UseSplitterOptions {\n /** Initial panel sizes as percentages (0–100). Should sum to 100. */\n defaultSizes?: number[]\n}\n\nexport interface UseSplitterReturn {\n /** Reactive array of panel sizes as percentages. */\n sizes: Ref<number[]>\n /** Set panel sizes directly. */\n setSizes: (sizes: number[]) => void\n /** Reset panel sizes to the values provided in `defaultSizes`. */\n resetSizes: () => void\n /**\n * Pass as `@layout` handler on the SplitterGroup component.\n * Keeps `sizes` in sync when the user drags the resize handle.\n */\n onLayout: (sizes: number[]) => void\n}\n\n/**\n * Tracks panel layout state for the SplitterGroup component.\n *\n * @example\n * ```ts\n * const splitter = useSplitter({ defaultSizes: [30, 70] })\n * ```\n * ```html\n * <SplitterGroup @layout=\"splitter.onLayout\">\n * <SplitterPanel :default-size=\"splitter.sizes[0] ?? 30\" />\n * <SplitterResizeHandle />\n * <SplitterPanel :default-size=\"splitter.sizes[1] ?? 70\" />\n * </SplitterGroup>\n * ```\n */\nexport function useSplitter(options: UseSplitterOptions = {}): UseSplitterReturn {\n const sizes = ref<number[]>(options.defaultSizes ? [...options.defaultSizes] : [])\n\n function setSizes(next: number[]): void {\n sizes.value = [...next]\n }\n\n function resetSizes(): void {\n sizes.value = options.defaultSizes ? [...options.defaultSizes] : []\n }\n\n function onLayout(next: number[]): void {\n sizes.value = next\n }\n\n return {\n sizes,\n setSizes,\n resetSizes,\n onLayout,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAoCA,SAAgB,YAAY,UAA8B,EAAE,EAAqB;CAC/E,MAAM,QAAQ,IAAc,QAAQ,eAAe,CAAC,GAAG,QAAQ,aAAa,GAAG,EAAE,CAAC;CAElF,SAAS,SAAS,MAAsB;AACtC,QAAM,QAAQ,CAAC,GAAG,KAAK;;CAGzB,SAAS,aAAmB;AAC1B,QAAM,QAAQ,QAAQ,eAAe,CAAC,GAAG,QAAQ,aAAa,GAAG,EAAE;;CAGrE,SAAS,SAAS,MAAsB;AACtC,QAAM,QAAQ;;AAGhB,QAAO;EACL;EACA;EACA;EACA;EACD"}
@@ -0,0 +1,58 @@
1
+ import { computed, ref } from "vue";
2
+ //#region src/composables/useStepper.ts
3
+ /**
4
+ * Manages step navigation state for the Stepper component.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const stepper = useStepper({ totalSteps: 4 })
9
+ * ```
10
+ * ```html
11
+ * <Stepper :model-value="stepper.step" :total-steps="stepper.totalSteps" @update:model-value="stepper.onStepChange">
12
+ * ...
13
+ * </Stepper>
14
+ * ```
15
+ */
16
+ function useStepper(options = {}) {
17
+ const step = ref(options.defaultStep ?? 1);
18
+ const totalSteps = computed(() => options.steps ? options.steps.length : options.totalSteps ?? 0);
19
+ const isFirst = computed(() => step.value <= 1);
20
+ const isLast = computed(() => totalSteps.value > 0 && step.value >= totalSteps.value);
21
+ function goToStep(n) {
22
+ const max = totalSteps.value || Infinity;
23
+ step.value = Math.max(1, Math.min(n, max));
24
+ }
25
+ function nextStep() {
26
+ if (!isLast.value) goToStep(step.value + 1);
27
+ }
28
+ function prevStep() {
29
+ if (!isFirst.value) goToStep(step.value - 1);
30
+ }
31
+ function reset() {
32
+ goToStep(1);
33
+ }
34
+ function getStepStatus(n) {
35
+ if (n < step.value) return "completed";
36
+ if (n === step.value) return "current";
37
+ return "pending";
38
+ }
39
+ function onStepChange(n) {
40
+ goToStep(n);
41
+ }
42
+ return {
43
+ step,
44
+ totalSteps,
45
+ isFirst,
46
+ isLast,
47
+ goToStep,
48
+ nextStep,
49
+ prevStep,
50
+ reset,
51
+ getStepStatus,
52
+ onStepChange
53
+ };
54
+ }
55
+ //#endregion
56
+ export { useStepper };
57
+
58
+ //# sourceMappingURL=useStepper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStepper.js","names":[],"sources":["../../src/composables/useStepper.ts"],"sourcesContent":["import { ref, computed, type Ref, type ComputedRef } from 'vue'\n\nexport type StepStatus = 'completed' | 'current' | 'pending'\n\nexport interface UseStepperOptions {\n /** Total number of steps. Ignored when `steps` array is provided. */\n totalSteps?: number\n /** Step items — `totalSteps` is derived from `steps.length` when provided. */\n steps?: unknown[]\n /** Initial step for uncontrolled usage. Defaults to 1. */\n defaultStep?: number\n}\n\nexport interface UseStepperReturn {\n /** Reactive current step (1-based). */\n step: Ref<number>\n /** Total number of steps. */\n totalSteps: ComputedRef<number>\n /** Whether the stepper is on the first step. */\n isFirst: ComputedRef<boolean>\n /** Whether the stepper is on the last step. */\n isLast: ComputedRef<boolean>\n /** Navigate to a specific step number. Clamps to valid range. */\n goToStep: (step: number) => void\n /** Advance to the next step. No-op on the last step. */\n nextStep: () => void\n /** Go back to the previous step. No-op on the first step. */\n prevStep: () => void\n /** Return to the first step. */\n reset: () => void\n /** Returns the display status for a given step number. */\n getStepStatus: (step: number) => StepStatus\n /**\n * Pass as `@update:model-value` handler on the Stepper component.\n * Keeps `step` in sync when the component changes step internally.\n */\n onStepChange: (step: number) => void\n}\n\n/**\n * Manages step navigation state for the Stepper component.\n *\n * @example\n * ```ts\n * const stepper = useStepper({ totalSteps: 4 })\n * ```\n * ```html\n * <Stepper :model-value=\"stepper.step\" :total-steps=\"stepper.totalSteps\" @update:model-value=\"stepper.onStepChange\">\n * ...\n * </Stepper>\n * ```\n */\nexport function useStepper(options: UseStepperOptions = {}): UseStepperReturn {\n const step = ref(options.defaultStep ?? 1)\n\n const totalSteps = computed(() =>\n options.steps ? options.steps.length : (options.totalSteps ?? 0)\n )\n\n const isFirst = computed(() => step.value <= 1)\n const isLast = computed(() => totalSteps.value > 0 && step.value >= totalSteps.value)\n\n function goToStep(n: number): void {\n const max = totalSteps.value || Infinity\n step.value = Math.max(1, Math.min(n, max))\n }\n\n function nextStep(): void {\n if (!isLast.value) goToStep(step.value + 1)\n }\n\n function prevStep(): void {\n if (!isFirst.value) goToStep(step.value - 1)\n }\n\n function reset(): void {\n goToStep(1)\n }\n\n function getStepStatus(n: number): StepStatus {\n if (n < step.value) return 'completed'\n if (n === step.value) return 'current'\n return 'pending'\n }\n\n function onStepChange(n: number): void {\n goToStep(n)\n }\n\n return {\n step,\n totalSteps,\n isFirst,\n isLast,\n goToStep,\n nextStep,\n prevStep,\n reset,\n getStepStatus,\n onStepChange,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAoDA,SAAgB,WAAW,UAA6B,EAAE,EAAoB;CAC5E,MAAM,OAAO,IAAI,QAAQ,eAAe,EAAE;CAE1C,MAAM,aAAa,eACjB,QAAQ,QAAQ,QAAQ,MAAM,SAAU,QAAQ,cAAc,EAC/D;CAED,MAAM,UAAU,eAAe,KAAK,SAAS,EAAE;CAC/C,MAAM,SAAS,eAAe,WAAW,QAAQ,KAAK,KAAK,SAAS,WAAW,MAAM;CAErF,SAAS,SAAS,GAAiB;EACjC,MAAM,MAAM,WAAW,SAAS;AAChC,OAAK,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;;CAG5C,SAAS,WAAiB;AACxB,MAAI,CAAC,OAAO,MAAO,UAAS,KAAK,QAAQ,EAAE;;CAG7C,SAAS,WAAiB;AACxB,MAAI,CAAC,QAAQ,MAAO,UAAS,KAAK,QAAQ,EAAE;;CAG9C,SAAS,QAAc;AACrB,WAAS,EAAE;;CAGb,SAAS,cAAc,GAAuB;AAC5C,MAAI,IAAI,KAAK,MAAO,QAAO;AAC3B,MAAI,MAAM,KAAK,MAAO,QAAO;AAC7B,SAAO;;CAGT,SAAS,aAAa,GAAiB;AACrC,WAAS,EAAE;;AAGb,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD"}
@@ -0,0 +1,31 @@
1
+ import { computed, readonly, ref } from "vue";
2
+ //#region src/composables/useSwatchPicker.ts
3
+ function useSwatchPicker(options = {}) {
4
+ const _selectedColor = ref(options.defaultValue ?? "");
5
+ const hasSelection = computed(() => _selectedColor.value !== "");
6
+ function setColor(hex) {
7
+ _selectedColor.value = hex;
8
+ options.onChange?.(hex);
9
+ }
10
+ function clearSelection() {
11
+ _selectedColor.value = "";
12
+ }
13
+ function isSelected(hex) {
14
+ return _selectedColor.value === hex;
15
+ }
16
+ function onColorChange(hex) {
17
+ setColor(hex);
18
+ }
19
+ return {
20
+ selectedColor: readonly(_selectedColor),
21
+ hasSelection,
22
+ setColor,
23
+ clearSelection,
24
+ isSelected,
25
+ onColorChange
26
+ };
27
+ }
28
+ //#endregion
29
+ export { useSwatchPicker };
30
+
31
+ //# sourceMappingURL=useSwatchPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSwatchPicker.js","names":[],"sources":["../../src/composables/useSwatchPicker.ts"],"sourcesContent":["import { ref, computed, readonly, type Ref, type ComputedRef } from 'vue'\n\nexport interface UseSwatchPickerOptions {\n /** Initial selected color as a hex string (e.g. '#ff0000'). */\n defaultValue?: string\n /** Fires when a swatch is selected with the new hex color. */\n onChange?: (hex: string) => void\n}\n\nexport interface UseSwatchPickerReturn {\n /** The currently selected color as a hex string. */\n selectedColor: Readonly<Ref<string>>\n /** True when a color is selected (non-empty). */\n hasSelection: ComputedRef<boolean>\n /** Select a color by hex string. */\n setColor: (hex: string) => void\n /** Clear the selection. */\n clearSelection: () => void\n /** Returns true if the given hex string is the currently selected color. */\n isSelected: (hex: string) => boolean\n /** Pass as `@update:model-value` on the ColorSwatchPicker component. */\n onColorChange: (hex: string) => void\n}\n\nexport function useSwatchPicker(options: UseSwatchPickerOptions = {}): UseSwatchPickerReturn {\n const _selectedColor = ref(options.defaultValue ?? '')\n\n const hasSelection = computed(() => _selectedColor.value !== '')\n\n function setColor(hex: string): void {\n _selectedColor.value = hex\n options.onChange?.(hex)\n }\n\n function clearSelection(): void {\n _selectedColor.value = ''\n }\n\n function isSelected(hex: string): boolean {\n return _selectedColor.value === hex\n }\n\n function onColorChange(hex: string): void {\n setColor(hex)\n }\n\n return {\n selectedColor: readonly(_selectedColor),\n hasSelection,\n setColor,\n clearSelection,\n isSelected,\n onColorChange,\n }\n}\n"],"mappings":";;AAwBA,SAAgB,gBAAgB,UAAkC,EAAE,EAAyB;CAC3F,MAAM,iBAAiB,IAAI,QAAQ,gBAAgB,GAAG;CAEtD,MAAM,eAAe,eAAe,eAAe,UAAU,GAAG;CAEhE,SAAS,SAAS,KAAmB;AACnC,iBAAe,QAAQ;AACvB,UAAQ,WAAW,IAAI;;CAGzB,SAAS,iBAAuB;AAC9B,iBAAe,QAAQ;;CAGzB,SAAS,WAAW,KAAsB;AACxC,SAAO,eAAe,UAAU;;CAGlC,SAAS,cAAc,KAAmB;AACxC,WAAS,IAAI;;AAGf,QAAO;EACL,eAAe,SAAS,eAAe;EACvC;EACA;EACA;EACA;EACA;EACD"}
@@ -0,0 +1,34 @@
1
+ import { ref } from "vue";
2
+ //#region src/composables/useTabs.ts
3
+ /**
4
+ * Manages active tab state for the Tabs component.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const tabs = useTabs({ defaultTab: 'overview' })
9
+ * ```
10
+ * ```html
11
+ * <Tabs :model-value="tabs.activeTab" @update:model-value="tabs.onTabChange">
12
+ * <Tab value="overview">Overview</Tab>
13
+ * <Tab value="settings">Settings</Tab>
14
+ * </Tabs>
15
+ * ```
16
+ */
17
+ function useTabs(options = {}) {
18
+ const activeTab = ref(options.defaultTab);
19
+ function setTab(value) {
20
+ activeTab.value = value;
21
+ }
22
+ function onTabChange(value) {
23
+ activeTab.value = value;
24
+ }
25
+ return {
26
+ activeTab,
27
+ setTab,
28
+ onTabChange
29
+ };
30
+ }
31
+ //#endregion
32
+ export { useTabs };
33
+
34
+ //# sourceMappingURL=useTabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTabs.js","names":[],"sources":["../../src/composables/useTabs.ts"],"sourcesContent":["import { ref, type Ref } from 'vue'\n\nexport interface UseTabsOptions {\n /** Initial active tab value. */\n defaultTab?: string\n}\n\nexport interface UseTabsReturn {\n /** Reactive active tab value. */\n activeTab: Ref<string | undefined>\n /** Set the active tab. */\n setTab: (value: string) => void\n /**\n * Pass as `@update:model-value` handler on the Tabs component.\n * Keeps `activeTab` in sync when the component changes tabs internally.\n */\n onTabChange: (value: string) => void\n}\n\n/**\n * Manages active tab state for the Tabs component.\n *\n * @example\n * ```ts\n * const tabs = useTabs({ defaultTab: 'overview' })\n * ```\n * ```html\n * <Tabs :model-value=\"tabs.activeTab\" @update:model-value=\"tabs.onTabChange\">\n * <Tab value=\"overview\">Overview</Tab>\n * <Tab value=\"settings\">Settings</Tab>\n * </Tabs>\n * ```\n */\nexport function useTabs(options: UseTabsOptions = {}): UseTabsReturn {\n const activeTab = ref<string | undefined>(options.defaultTab)\n\n function setTab(value: string): void {\n activeTab.value = value\n }\n\n function onTabChange(value: string): void {\n activeTab.value = value\n }\n\n return {\n activeTab,\n setTab,\n onTabChange,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiCA,SAAgB,QAAQ,UAA0B,EAAE,EAAiB;CACnE,MAAM,YAAY,IAAwB,QAAQ,WAAW;CAE7D,SAAS,OAAO,OAAqB;AACnC,YAAU,QAAQ;;CAGpB,SAAS,YAAY,OAAqB;AACxC,YAAU,QAAQ;;AAGpB,QAAO;EACL;EACA;EACA;EACD"}
@@ -0,0 +1,88 @@
1
+ import { ref } from "vue";
2
+ //#region src/composables/useTree.ts
3
+ /**
4
+ * Manages selection and expansion state for the Tree component.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const tree = useTree({ multiple: false, defaultExpanded: ['root'] })
9
+ * ```
10
+ * ```html
11
+ * <Tree
12
+ * :model-value="tree.selected"
13
+ * :expanded="tree.expanded"
14
+ * @update:model-value="tree.onSelectionChange"
15
+ * @update:expanded="tree.onExpandedChange"
16
+ * >
17
+ * ...
18
+ * </Tree>
19
+ * ```
20
+ */
21
+ function useTree(options = {}) {
22
+ const multiple = options.multiple ?? false;
23
+ const selected = ref(options.defaultSelected ?? (multiple ? [] : void 0));
24
+ const expanded = ref(options.defaultExpanded ? [...options.defaultExpanded] : []);
25
+ function isSelected(key) {
26
+ if (Array.isArray(selected.value)) return selected.value.includes(key);
27
+ return selected.value === key;
28
+ }
29
+ function select(key) {
30
+ if (multiple) {
31
+ const current = selected.value ?? [];
32
+ if (!current.includes(key)) selected.value = [...current, key];
33
+ } else selected.value = key;
34
+ }
35
+ function deselect(key) {
36
+ if (multiple) selected.value = (selected.value ?? []).filter((k) => k !== key);
37
+ else if (selected.value === key) selected.value = void 0;
38
+ }
39
+ function toggle(key) {
40
+ if (isSelected(key)) deselect(key);
41
+ else select(key);
42
+ }
43
+ function isExpanded(key) {
44
+ return expanded.value.includes(key);
45
+ }
46
+ function expand(key) {
47
+ if (!isExpanded(key)) expanded.value = [...expanded.value, key];
48
+ }
49
+ function collapse(key) {
50
+ expanded.value = expanded.value.filter((k) => k !== key);
51
+ }
52
+ function toggleExpand(key) {
53
+ if (isExpanded(key)) collapse(key);
54
+ else expand(key);
55
+ }
56
+ function expandAll(keys) {
57
+ expanded.value = [...new Set([...expanded.value, ...keys])];
58
+ }
59
+ function collapseAll() {
60
+ expanded.value = [];
61
+ }
62
+ function onSelectionChange(value) {
63
+ selected.value = value;
64
+ }
65
+ function onExpandedChange(keys) {
66
+ expanded.value = keys;
67
+ }
68
+ return {
69
+ selected,
70
+ expanded,
71
+ isSelected,
72
+ select,
73
+ deselect,
74
+ toggle,
75
+ isExpanded,
76
+ expand,
77
+ collapse,
78
+ toggleExpand,
79
+ expandAll,
80
+ collapseAll,
81
+ onSelectionChange,
82
+ onExpandedChange
83
+ };
84
+ }
85
+ //#endregion
86
+ export { useTree };
87
+
88
+ //# sourceMappingURL=useTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTree.js","names":[],"sources":["../../src/composables/useTree.ts"],"sourcesContent":["import { ref, type Ref } from 'vue'\n\nexport type TreeValue = string | string[] | undefined\n\nexport interface UseTreeOptions {\n /** Enable multi-selection. Defaults to false. */\n multiple?: boolean\n /** Initial selected node key(s). */\n defaultSelected?: TreeValue\n /** Initial expanded node keys. */\n defaultExpanded?: string[]\n}\n\nexport interface UseTreeReturn {\n /** Reactive selected node key(s). String in single mode, string[] in multiple mode. */\n selected: Ref<TreeValue>\n /** Reactive array of expanded node keys. */\n expanded: Ref<string[]>\n /** Whether a given node is currently selected. */\n isSelected: (key: string) => boolean\n /** Select a node. In single mode, replaces the current selection. */\n select: (key: string) => void\n /** Deselect a node. */\n deselect: (key: string) => void\n /** Toggle a node's selection state. */\n toggle: (key: string) => void\n /** Whether a given node is currently expanded. */\n isExpanded: (key: string) => boolean\n /** Expand a node. */\n expand: (key: string) => void\n /** Collapse a node. */\n collapse: (key: string) => void\n /** Toggle a node's expanded state. */\n toggleExpand: (key: string) => void\n /** Expand all provided node keys. */\n expandAll: (keys: string[]) => void\n /** Collapse all expanded nodes. */\n collapseAll: () => void\n /**\n * Pass as `@update:model-value` on the Tree component.\n * Keeps `selected` in sync when the component changes selection internally.\n */\n onSelectionChange: (value: TreeValue) => void\n /**\n * Pass as `@update:expanded` on the Tree component.\n * Keeps `expanded` in sync when the component changes expanded state internally.\n */\n onExpandedChange: (keys: string[]) => void\n}\n\n/**\n * Manages selection and expansion state for the Tree component.\n *\n * @example\n * ```ts\n * const tree = useTree({ multiple: false, defaultExpanded: ['root'] })\n * ```\n * ```html\n * <Tree\n * :model-value=\"tree.selected\"\n * :expanded=\"tree.expanded\"\n * @update:model-value=\"tree.onSelectionChange\"\n * @update:expanded=\"tree.onExpandedChange\"\n * >\n * ...\n * </Tree>\n * ```\n */\nexport function useTree(options: UseTreeOptions = {}): UseTreeReturn {\n const multiple = options.multiple ?? false\n\n const selected = ref<TreeValue>(\n options.defaultSelected ?? (multiple ? [] : undefined)\n )\n const expanded = ref<string[]>(options.defaultExpanded ? [...options.defaultExpanded] : [])\n\n function isSelected(key: string): boolean {\n if (Array.isArray(selected.value)) return selected.value.includes(key)\n return selected.value === key\n }\n\n function select(key: string): void {\n if (multiple) {\n const current = (selected.value as string[]) ?? []\n if (!current.includes(key)) selected.value = [...current, key]\n } else {\n selected.value = key\n }\n }\n\n function deselect(key: string): void {\n if (multiple) {\n selected.value = ((selected.value as string[]) ?? []).filter(k => k !== key)\n } else if (selected.value === key) {\n selected.value = undefined\n }\n }\n\n function toggle(key: string): void {\n if (isSelected(key)) deselect(key)\n else select(key)\n }\n\n function isExpanded(key: string): boolean {\n return expanded.value.includes(key)\n }\n\n function expand(key: string): void {\n if (!isExpanded(key)) expanded.value = [...expanded.value, key]\n }\n\n function collapse(key: string): void {\n expanded.value = expanded.value.filter(k => k !== key)\n }\n\n function toggleExpand(key: string): void {\n if (isExpanded(key)) collapse(key)\n else expand(key)\n }\n\n function expandAll(keys: string[]): void {\n expanded.value = [...new Set([...expanded.value, ...keys])]\n }\n\n function collapseAll(): void {\n expanded.value = []\n }\n\n function onSelectionChange(value: TreeValue): void {\n selected.value = value\n }\n\n function onExpandedChange(keys: string[]): void {\n expanded.value = keys\n }\n\n return {\n selected,\n expanded,\n isSelected,\n select,\n deselect,\n toggle,\n isExpanded,\n expand,\n collapse,\n toggleExpand,\n expandAll,\n collapseAll,\n onSelectionChange,\n onExpandedChange,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoEA,SAAgB,QAAQ,UAA0B,EAAE,EAAiB;CACnE,MAAM,WAAW,QAAQ,YAAY;CAErC,MAAM,WAAW,IACf,QAAQ,oBAAoB,WAAW,EAAE,GAAG,KAAA,GAC7C;CACD,MAAM,WAAW,IAAc,QAAQ,kBAAkB,CAAC,GAAG,QAAQ,gBAAgB,GAAG,EAAE,CAAC;CAE3F,SAAS,WAAW,KAAsB;AACxC,MAAI,MAAM,QAAQ,SAAS,MAAM,CAAE,QAAO,SAAS,MAAM,SAAS,IAAI;AACtE,SAAO,SAAS,UAAU;;CAG5B,SAAS,OAAO,KAAmB;AACjC,MAAI,UAAU;GACZ,MAAM,UAAW,SAAS,SAAsB,EAAE;AAClD,OAAI,CAAC,QAAQ,SAAS,IAAI,CAAE,UAAS,QAAQ,CAAC,GAAG,SAAS,IAAI;QAE9D,UAAS,QAAQ;;CAIrB,SAAS,SAAS,KAAmB;AACnC,MAAI,SACF,UAAS,SAAU,SAAS,SAAsB,EAAE,EAAE,QAAO,MAAK,MAAM,IAAI;WACnE,SAAS,UAAU,IAC5B,UAAS,QAAQ,KAAA;;CAIrB,SAAS,OAAO,KAAmB;AACjC,MAAI,WAAW,IAAI,CAAE,UAAS,IAAI;MAC7B,QAAO,IAAI;;CAGlB,SAAS,WAAW,KAAsB;AACxC,SAAO,SAAS,MAAM,SAAS,IAAI;;CAGrC,SAAS,OAAO,KAAmB;AACjC,MAAI,CAAC,WAAW,IAAI,CAAE,UAAS,QAAQ,CAAC,GAAG,SAAS,OAAO,IAAI;;CAGjE,SAAS,SAAS,KAAmB;AACnC,WAAS,QAAQ,SAAS,MAAM,QAAO,MAAK,MAAM,IAAI;;CAGxD,SAAS,aAAa,KAAmB;AACvC,MAAI,WAAW,IAAI,CAAE,UAAS,IAAI;MAC7B,QAAO,IAAI;;CAGlB,SAAS,UAAU,MAAsB;AACvC,WAAS,QAAQ,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,SAAS,OAAO,GAAG,KAAK,CAAC,CAAC;;CAG7D,SAAS,cAAoB;AAC3B,WAAS,QAAQ,EAAE;;CAGrB,SAAS,kBAAkB,OAAwB;AACjD,WAAS,QAAQ;;CAGnB,SAAS,iBAAiB,MAAsB;AAC9C,WAAS,QAAQ;;AAGnB,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD"}