@baklavue/ui 1.0.0-preview.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 (83) hide show
  1. package/.releaserc.json +14 -0
  2. package/CHANGELOG.md +40 -0
  3. package/README.md +15 -0
  4. package/index.ts +1 -0
  5. package/package.json +45 -0
  6. package/src/accordion/Accordion.vue +206 -0
  7. package/src/accordion/accordion.types.ts +109 -0
  8. package/src/accordion/index.ts +3 -0
  9. package/src/alert/Alert.vue +199 -0
  10. package/src/alert/alert.types.ts +58 -0
  11. package/src/alert/index.ts +2 -0
  12. package/src/badge/Badge.vue +20 -0
  13. package/src/badge/badge.types.ts +7 -0
  14. package/src/badge/index.ts +2 -0
  15. package/src/button/Button.vue +45 -0
  16. package/src/button/button.types.ts +30 -0
  17. package/src/button/index.ts +3 -0
  18. package/src/checkbox/Checkbox.vue +148 -0
  19. package/src/checkbox/checkbox.types.ts +108 -0
  20. package/src/checkbox/index.ts +2 -0
  21. package/src/datepicker/Datepicker.vue +172 -0
  22. package/src/datepicker/datepicker.types.ts +39 -0
  23. package/src/datepicker/index.ts +2 -0
  24. package/src/dialog/Dialog.vue +178 -0
  25. package/src/dialog/dialog.types.ts +17 -0
  26. package/src/dialog/index.ts +2 -0
  27. package/src/drawer/Drawer.vue +162 -0
  28. package/src/drawer/drawer.types.ts +17 -0
  29. package/src/drawer/index.ts +2 -0
  30. package/src/dropdown/Dropdown.vue +231 -0
  31. package/src/dropdown/dropdown.types.ts +110 -0
  32. package/src/dropdown/index.ts +2 -0
  33. package/src/icon/Icon.vue +102 -0
  34. package/src/icon/icon.types.ts +25 -0
  35. package/src/icon/index.ts +2 -0
  36. package/src/index.ts +37 -0
  37. package/src/input/Input.vue +148 -0
  38. package/src/input/index.ts +3 -0
  39. package/src/input/input.types.ts +156 -0
  40. package/src/link/Link.vue +133 -0
  41. package/src/link/index.ts +2 -0
  42. package/src/link/link.types.ts +42 -0
  43. package/src/notification/Notification.vue +57 -0
  44. package/src/notification/index.ts +2 -0
  45. package/src/notification/notification.types.ts +25 -0
  46. package/src/pagination/Pagination.vue +137 -0
  47. package/src/pagination/index.ts +2 -0
  48. package/src/pagination/pagination.types.ts +61 -0
  49. package/src/radio/Radio.vue +205 -0
  50. package/src/radio/index.ts +2 -0
  51. package/src/radio/radio.types.ts +95 -0
  52. package/src/select/Select.vue +147 -0
  53. package/src/select/index.ts +2 -0
  54. package/src/select/select.types.ts +53 -0
  55. package/src/spinner/Spinner.vue +49 -0
  56. package/src/spinner/index.ts +2 -0
  57. package/src/spinner/spinner.types.ts +11 -0
  58. package/src/split-button/SplitButton.vue +73 -0
  59. package/src/split-button/index.ts +2 -0
  60. package/src/split-button/split-button.types.ts +19 -0
  61. package/src/stepper/Stepper.vue +100 -0
  62. package/src/stepper/index.ts +2 -0
  63. package/src/stepper/stepper.types.ts +29 -0
  64. package/src/switch/Switch.vue +80 -0
  65. package/src/switch/index.ts +2 -0
  66. package/src/switch/switch.types.ts +13 -0
  67. package/src/tab/Tab.vue +99 -0
  68. package/src/tab/index.ts +2 -0
  69. package/src/tab/tab.types.ts +17 -0
  70. package/src/table/Table.vue +264 -0
  71. package/src/table/index.ts +7 -0
  72. package/src/table/table.types.ts +62 -0
  73. package/src/tag/Tag.vue +83 -0
  74. package/src/tag/index.ts +2 -0
  75. package/src/tag/tag.types.ts +24 -0
  76. package/src/textarea/Textarea.vue +84 -0
  77. package/src/textarea/index.ts +2 -0
  78. package/src/textarea/textarea.types.ts +37 -0
  79. package/src/tooltip/Tooltip.vue +81 -0
  80. package/src/tooltip/index.ts +3 -0
  81. package/src/tooltip/tooltip.types.ts +29 -0
  82. package/src/utils/loadBaklavaResources.ts +24 -0
  83. package/tsconfig.json +28 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Properties for a single radio item when used in group mode.
3
+ *
4
+ * @interface RadioItem
5
+ */
6
+ export interface RadioItem {
7
+ /**
8
+ * The value of the radio (used for v-model in group mode).
9
+ */
10
+ value: string | number;
11
+
12
+ /**
13
+ * The label text displayed next to the radio.
14
+ */
15
+ label?: string;
16
+
17
+ /**
18
+ * Whether the radio is disabled.
19
+ *
20
+ * @default false
21
+ */
22
+ disabled?: boolean;
23
+
24
+ /**
25
+ * The name attribute for the radio group.
26
+ */
27
+ name?: string;
28
+
29
+ /**
30
+ * Additional custom data for use in the #item scoped slot.
31
+ */
32
+ [key: string]: unknown;
33
+ }
34
+
35
+ /**
36
+ * Props for the Radio component.
37
+ *
38
+ * When `items` prop is provided, the component acts as a radio group container.
39
+ * Otherwise, it acts as a single radio option.
40
+ *
41
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio
42
+ */
43
+ export interface RadioProps {
44
+ /**
45
+ * Selected value (single mode or group mode).
46
+ * Use v-model for two-way binding.
47
+ * - Single mode: used with value prop for comparison
48
+ * - Group mode: the selected item's value
49
+ */
50
+ modelValue?: string | number;
51
+
52
+ /**
53
+ * This radio option's value. Used for v-model comparison and form submission.
54
+ * Only used when component is in single radio mode.
55
+ */
56
+ value?: string | number;
57
+
58
+ /**
59
+ * Name attribute for the radio group. All radios in the same group must share the same name.
60
+ * Only used when component is in single radio mode.
61
+ */
62
+ name?: string;
63
+
64
+ /**
65
+ * Label text displayed next to the radio. Can be overridden by the default slot.
66
+ * Only used when component is in single radio mode.
67
+ */
68
+ label?: string;
69
+
70
+ /**
71
+ * Boolean to explicitly control checked state.
72
+ * When provided, overrides modelValue === value logic.
73
+ * Only used when component is in single radio mode.
74
+ */
75
+ checked?: boolean;
76
+
77
+ /**
78
+ * Whether the radio is disabled.
79
+ * Only used when component is in single radio mode.
80
+ */
81
+ disabled?: boolean;
82
+
83
+ /**
84
+ * Whether the radio group is required (for form validation).
85
+ * Used in group mode on bl-radio-group.
86
+ */
87
+ required?: boolean;
88
+
89
+ /**
90
+ * Array of radio items to render when in group mode.
91
+ * Each item will be rendered as a bl-radio element inside bl-radio-group.
92
+ * Only used when component is in group mode.
93
+ */
94
+ items?: RadioItem[];
95
+ }
@@ -0,0 +1,147 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Select Component
4
+ *
5
+ * A Vue UI kit component for Baklava's `bl-select` web component with v-model support.
6
+ * Supports both slot-based options and the `options` prop for programmatic rendering.
7
+ *
8
+ * @component
9
+ * @example
10
+ * ```vue
11
+ * <!-- Basic single select with slot -->
12
+ * <template>
13
+ * <BvSelect v-model="selected" label="Choose an option">
14
+ * <bl-select-option value="a">Option A</bl-select-option>
15
+ * <bl-select-option value="b">Option B</bl-select-option>
16
+ * </BvSelect>
17
+ * </template>
18
+ * ```
19
+ *
20
+ * @example
21
+ * ```vue
22
+ * <!-- Options array -->
23
+ * <template>
24
+ * <BvSelect v-model="country" label="Country" :options="countries" />
25
+ * </template>
26
+ * ```
27
+ *
28
+ * @example
29
+ * ```vue
30
+ * <!-- Multiple select -->
31
+ * <template>
32
+ * <BvSelect v-model="selected" label="Select multiple" :multiple="true" :options="items" />
33
+ * </template>
34
+ * ```
35
+ */
36
+ import { computed, onMounted } from "vue";
37
+ import { loadBaklavaResources } from "../utils/loadBaklavaResources";
38
+ import type { SelectProps } from "./select.types";
39
+
40
+ /**
41
+ * Component props with default values.
42
+ */
43
+ const props = withDefaults(defineProps<SelectProps>(), {
44
+ modelValue: undefined,
45
+ options: undefined,
46
+ label: undefined,
47
+ placeholder: undefined,
48
+ name: undefined,
49
+ required: undefined,
50
+ disabled: undefined,
51
+ multiple: undefined,
52
+ size: undefined,
53
+ clearable: undefined,
54
+ helpText: undefined,
55
+ customInvalidText: undefined,
56
+ searchBar: undefined,
57
+ searchBarPlaceholder: undefined,
58
+ });
59
+
60
+ /**
61
+ * Component events.
62
+ */
63
+ const emit = defineEmits<{
64
+ /**
65
+ * Emitted when the selection changes. Use with v-model.
66
+ *
67
+ * @param {string | string[] | null} value - The selected value(s). Array when multiple.
68
+ */
69
+ "update:modelValue": [value: string | string[] | null];
70
+ /**
71
+ * Emitted when selection changes (bl-change event).
72
+ *
73
+ * @param {CustomEvent} event - The native bl-change event from bl-select.
74
+ */
75
+ change: [event: CustomEvent];
76
+ /**
77
+ * Emitted on input (bl-input event).
78
+ *
79
+ * @param {CustomEvent} event - The native bl-input event from bl-select.
80
+ */
81
+ input: [event: CustomEvent];
82
+ }>();
83
+
84
+ /**
85
+ * Handles the bl-change event from the underlying bl-select component.
86
+ * Syncs v-model and forwards the change event.
87
+ * The bl-select element (event.target) exposes a .value property for the selected value.
88
+ *
89
+ * @param {CustomEvent} event - The bl-change event from bl-select.
90
+ */
91
+ const handleChange = (event: CustomEvent) => {
92
+ emit("change", event);
93
+ const target = event.target as HTMLSelectElement & {
94
+ value?: string | string[] | null;
95
+ };
96
+ emit("update:modelValue", target?.value ?? null);
97
+ };
98
+
99
+ /**
100
+ * Lifecycle hook: Component mounted.
101
+ *
102
+ * Loads Baklava resources when the component is mounted.
103
+ */
104
+ /**
105
+ * Props to pass to bl-select. Excludes modelValue (we use :value) and options
106
+ * (we render bl-select-option children from options in the template).
107
+ */
108
+ const selectProps = computed(() => {
109
+ const { modelValue: _, options: __, ...rest } = props;
110
+ return {
111
+ ...rest,
112
+ disabled: rest.disabled === true ? true : undefined,
113
+ multiple: rest.multiple === true ? true : undefined,
114
+ "help-text": rest.helpText ?? undefined,
115
+ "invalid-text": rest.customInvalidText ?? undefined,
116
+ "search-bar": rest.searchBar === true ? true : undefined,
117
+ "search-bar-placeholder": rest.searchBarPlaceholder ?? undefined,
118
+ };
119
+ });
120
+
121
+ onMounted(() => {
122
+ loadBaklavaResources();
123
+ });
124
+ </script>
125
+
126
+ <template>
127
+ <bl-select
128
+ v-bind="selectProps"
129
+ :value="props.modelValue"
130
+ @bl-change="handleChange"
131
+ @bl-input="emit('input', $event)"
132
+ >
133
+ <!-- Render options from options prop when provided -->
134
+ <template v-if="options">
135
+ <bl-select-option
136
+ v-for="option in options"
137
+ :key="option.value"
138
+ :value="option.value"
139
+ :disabled="option.disabled"
140
+ >
141
+ {{ option.label }}
142
+ </bl-select-option>
143
+ </template>
144
+ <!-- Default slot for custom bl-select-option children -->
145
+ <slot />
146
+ </bl-select>
147
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as BvSelect } from "./Select.vue";
2
+ export type { SelectProps, SelectOption, SelectSize } from "./select.types";
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Size variants for the Select component.
3
+ * @see {@link https://baklavastyle.trendyol.com/components/select | Baklava Select}
4
+ */
5
+ export type SelectSize = "small" | "medium" | "large";
6
+
7
+ /**
8
+ * Option shape for the Select component's `options` prop.
9
+ * Each option can have a value, display label, and optional disabled state.
10
+ */
11
+ export interface SelectOption {
12
+ /** The value submitted with the form or bound via v-model */
13
+ value: string;
14
+ /** The label displayed to the user */
15
+ label: string;
16
+ /** Whether the option is disabled */
17
+ disabled?: boolean;
18
+ }
19
+
20
+ /**
21
+ * Props for the Select Vue UI kit component.
22
+ * Wraps Baklava's `bl-select` web component with v-model support.
23
+ */
24
+ export interface SelectProps {
25
+ /** Selected value(s) - use with v-model. Single value or array when multiple. */
26
+ modelValue?: string | string[] | null;
27
+ /** Array of options for programmatic option rendering. Alternative to default slot. */
28
+ options?: SelectOption[];
29
+ /** Label displayed above or as placeholder for the select */
30
+ label?: string;
31
+ /** Placeholder text when no value is selected */
32
+ placeholder?: string;
33
+ /** Select name attribute for form submission */
34
+ name?: string;
35
+ /** Whether the select is required (shows error state when empty) */
36
+ required?: boolean;
37
+ /** Whether the select is disabled */
38
+ disabled?: boolean;
39
+ /** Whether multiple options can be selected */
40
+ multiple?: boolean;
41
+ /** Size of the select: small, medium, or large */
42
+ size?: SelectSize;
43
+ /** Whether the selected value can be cleared */
44
+ clearable?: boolean;
45
+ /** Help text displayed below the select */
46
+ helpText?: string;
47
+ /** Custom error message for validation */
48
+ customInvalidText?: string;
49
+ /** Enable search/filter for options in the dropdown */
50
+ searchBar?: boolean;
51
+ /** Placeholder text for the search input */
52
+ searchBarPlaceholder?: string;
53
+ }
@@ -0,0 +1,49 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Spinner Component
4
+ *
5
+ * A Vue UI kit component for Baklava's `bl-spinner` web component for loading indicators.
6
+ * Displays an animated spinner with configurable size and variant.
7
+ *
8
+ * @component
9
+ * @example
10
+ * ```vue
11
+ * <template>
12
+ * <BvSpinner />
13
+ * </template>
14
+ * ```
15
+ *
16
+ * @example
17
+ * ```vue
18
+ * <template>
19
+ * <BvSpinner size="large" label="Loading..." />
20
+ * </template>
21
+ * ```
22
+ */
23
+ import { computed, onMounted } from "vue";
24
+ import { loadBaklavaResources } from "../utils/loadBaklavaResources";
25
+ import type { SpinnerProps } from "./spinner.types";
26
+
27
+ /**
28
+ * Component props with default values.
29
+ */
30
+ const props = withDefaults(defineProps<SpinnerProps>(), {
31
+ size: undefined,
32
+ variant: undefined,
33
+ label: undefined,
34
+ });
35
+
36
+ /** Props to pass to bl-spinner (excludes label, which is used for aria-label) */
37
+ const spinnerProps = computed(() => {
38
+ const { label: _, ...rest } = props;
39
+ return rest;
40
+ });
41
+
42
+ onMounted(() => {
43
+ loadBaklavaResources();
44
+ });
45
+ </script>
46
+
47
+ <template>
48
+ <bl-spinner v-bind="spinnerProps" :aria-label="label" />
49
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as BvSpinner } from "./Spinner.vue";
2
+ export type { SpinnerProps } from "./spinner.types";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Props for the Spinner component.
3
+ */
4
+ export interface SpinnerProps {
5
+ /** Spinner size (e.g. CSS variable or length like var(--bl-font-size-m)) */
6
+ size?: string;
7
+ /** Spinner variant/style */
8
+ variant?: string;
9
+ /** Accessible label for screen readers */
10
+ label?: string;
11
+ }
@@ -0,0 +1,73 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * SplitButton Component
4
+ *
5
+ * A Vue UI kit component for Baklava's `bl-split-button` web component.
6
+ * A button with a primary action and a dropdown for secondary actions.
7
+ * Dropdown content is provided via the `dropdown-content` slot.
8
+ *
9
+ * @component
10
+ * @example
11
+ * ```vue
12
+ * <template>
13
+ * <BvSplitButton label="Actions" @click="handleClick">
14
+ * <template #dropdown-content>
15
+ * <bl-dropdown-item>Action 1</bl-dropdown-item>
16
+ * <bl-dropdown-item>Action 2</bl-dropdown-item>
17
+ * </template>
18
+ * </BvSplitButton>
19
+ * </template>
20
+ * ```
21
+ *
22
+ * @example
23
+ * ```vue
24
+ * <template>
25
+ * <BvSplitButton label="Save" icon="check" variant="primary" @click="save" />
26
+ * </template>
27
+ * ```
28
+ */
29
+ import { onMounted } from "vue";
30
+ import { loadBaklavaResources } from "../utils/loadBaklavaResources";
31
+ import type { SplitButtonProps } from "./split-button.types";
32
+
33
+ const props = defineProps<SplitButtonProps>();
34
+
35
+ /**
36
+ * Component events.
37
+ */
38
+ const emit = defineEmits<{
39
+ /**
40
+ * Emitted when the main button is clicked.
41
+ *
42
+ * @param {CustomEvent} event - The native click event from bl-split-button.
43
+ */
44
+ click: [event: CustomEvent];
45
+ /**
46
+ * Emitted when the dropdown button is clicked.
47
+ *
48
+ * @param {CustomEvent} event - The native dropdown-click event from bl-split-button.
49
+ */
50
+ "dropdown-click": [event: CustomEvent];
51
+ }>();
52
+
53
+ onMounted(() => {
54
+ loadBaklavaResources();
55
+ });
56
+ </script>
57
+
58
+ <template>
59
+ <bl-split-button
60
+ v-bind="{
61
+ variant: props.variant,
62
+ size: props.size,
63
+ disabled: props.disabled === true ? true : undefined,
64
+ loading: props.loading === true ? true : undefined,
65
+ label: props.label,
66
+ icon: props.icon,
67
+ }"
68
+ @bl-click="emit('click', $event)"
69
+ @bl-dropdown-click="emit('dropdown-click', $event)"
70
+ >
71
+ <slot v-if="$slots['dropdown-content']" name="dropdown-content" />
72
+ </bl-split-button>
73
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as BvSplitButton } from "./SplitButton.vue";
2
+ export type { SplitButtonProps } from "./split-button.types";
@@ -0,0 +1,19 @@
1
+ import type { BaklavaIcon } from "@trendyol/baklava-icons";
2
+
3
+ /**
4
+ * Props for the SplitButton component.
5
+ */
6
+ export interface SplitButtonProps {
7
+ /** Button variant (primary, secondary) */
8
+ variant?: string;
9
+ /** Button size (small, medium, large) */
10
+ size?: string;
11
+ /** Whether the main button is disabled */
12
+ disabled?: boolean;
13
+ /** Loading state of the main button */
14
+ loading?: boolean;
15
+ /** Button label */
16
+ label?: string;
17
+ /** Icon name for the main button */
18
+ icon?: BaklavaIcon;
19
+ }
@@ -0,0 +1,100 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Stepper Component
4
+ *
5
+ * A Vue UI kit component for Baklava's `bl-stepper` web component for step indicators.
6
+ * Displays progress through a sequence of steps. Use the `steps` prop for declarative
7
+ * configuration or the default slot for custom step content.
8
+ *
9
+ * @component
10
+ * @example
11
+ * ```vue
12
+ * <template>
13
+ * <BvStepper v-model:current-step="currentStep" :steps="steps" />
14
+ * </template>
15
+ * ```
16
+ *
17
+ * @example
18
+ * ```vue
19
+ * <template>
20
+ * <BvStepper :steps="['Step 1', 'Step 2', 'Step 3']" />
21
+ * </template>
22
+ * ```
23
+ */
24
+ import { onMounted } from "vue";
25
+ import { loadBaklavaResources } from "../utils/loadBaklavaResources";
26
+ import type { StepperProps, StepperStep } from "./stepper.types";
27
+
28
+ /**
29
+ * Component props with default values.
30
+ */
31
+ const props = withDefaults(defineProps<StepperProps>(), {
32
+ currentStep: undefined,
33
+ steps: undefined,
34
+ orientation: undefined,
35
+ showLabels: undefined,
36
+ });
37
+
38
+ /**
39
+ * Component events.
40
+ */
41
+ const emit = defineEmits<{
42
+ /**
43
+ * Emitted when the current step changes (for v-model:currentStep).
44
+ *
45
+ * @param {number} step - The new current step index.
46
+ */
47
+ "update:currentStep": [step: number];
48
+ /**
49
+ * Emitted when the user selects a different step.
50
+ *
51
+ * @param {CustomEvent} event - The native bl-stepper-change event from bl-stepper.
52
+ */
53
+ "step-change": [event: CustomEvent];
54
+ }>();
55
+
56
+ /**
57
+ * Returns the variant for a step based on its index and the current step.
58
+ */
59
+ const getStepVariant = (index: number): "default" | "active" | "success" | "error" => {
60
+ const current = props.currentStep ?? 0;
61
+ const step = props.steps?.[index];
62
+ if (step?.error) return "error";
63
+ if (index < current) return "success";
64
+ if (index === current) return "active";
65
+ return "default";
66
+ };
67
+
68
+ /**
69
+ * Handles the bl-stepper-change event from the underlying web component.
70
+ */
71
+ const handleStepChange = (event: CustomEvent<{ activeStep: number; totalSteps: number }>) => {
72
+ emit("step-change", event);
73
+ const step = event.detail?.activeStep;
74
+ if (step !== undefined) emit("update:currentStep", step);
75
+ };
76
+
77
+ onMounted(() => {
78
+ loadBaklavaResources();
79
+ });
80
+ </script>
81
+
82
+ <template>
83
+ <bl-stepper
84
+ :direction="orientation ?? 'horizontal'"
85
+ @bl-stepper-change="handleStepChange"
86
+ >
87
+ <template v-if="steps">
88
+ <bl-stepper-item
89
+ v-for="(step, index) in steps"
90
+ :key="index"
91
+ :id="`step-${index}`"
92
+ :title="showLabels !== false ? step.label : ''"
93
+ :description="showLabels !== false && step.description ? step.description : ''"
94
+ :variant="getStepVariant(index)"
95
+ :disabled="step.disabled"
96
+ />
97
+ </template>
98
+ <slot />
99
+ </bl-stepper>
100
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as BvStepper } from "./Stepper.vue";
2
+ export type { StepperProps, StepperStep } from "./stepper.types";
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Configuration for a single step in the stepper.
3
+ */
4
+ export interface StepperStep {
5
+ /** Step label */
6
+ label: string;
7
+ /** Optional step description */
8
+ description?: string;
9
+ /** Whether the step is completed */
10
+ completed?: boolean;
11
+ /** Whether the step has an error state */
12
+ error?: boolean;
13
+ /** Whether the step is disabled */
14
+ disabled?: boolean;
15
+ }
16
+
17
+ /**
18
+ * Props for the Stepper component.
19
+ */
20
+ export interface StepperProps {
21
+ /** Current step index (0-based). Use with v-model:currentStep */
22
+ currentStep?: number;
23
+ /** Array of step configurations */
24
+ steps?: StepperStep[];
25
+ /** Layout direction (horizontal, vertical) */
26
+ orientation?: string;
27
+ /** Whether to show step labels */
28
+ showLabels?: boolean;
29
+ }
@@ -0,0 +1,80 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Switch Component
4
+ *
5
+ * A Vue UI kit component for Baklava's `bl-switch` web component with v-model support.
6
+ * A toggle switch for boolean states. Supports v-model:checked for two-way binding.
7
+ *
8
+ * @component
9
+ * @example
10
+ * ```vue
11
+ * <template>
12
+ * <BvSwitch v-model:checked="enabled" label="Enable notifications" />
13
+ * </template>
14
+ * ```
15
+ *
16
+ * @example
17
+ * ```vue
18
+ * <template>
19
+ * <BvSwitch :checked="isOn" @change="handleChange" />
20
+ * </template>
21
+ * ```
22
+ */
23
+ import { onMounted } from "vue";
24
+ import { loadBaklavaResources } from "../utils/loadBaklavaResources";
25
+ import type { SwitchProps } from "./switch.types";
26
+
27
+ /**
28
+ * Component props with default values.
29
+ */
30
+ const props = withDefaults(defineProps<SwitchProps>(), {
31
+ checked: undefined,
32
+ disabled: undefined,
33
+ label: undefined,
34
+ size: undefined,
35
+ });
36
+
37
+ /**
38
+ * Component events.
39
+ */
40
+ const emit = defineEmits<{
41
+ /**
42
+ * Emitted when the checked state changes (for v-model:checked).
43
+ *
44
+ * @param {boolean} checked - The new checked state.
45
+ */
46
+ "update:checked": [checked: boolean];
47
+ /**
48
+ * Emitted when the user toggles the switch.
49
+ *
50
+ * @param {CustomEvent} event - The native change event from bl-switch.
51
+ */
52
+ change: [event: CustomEvent];
53
+ /**
54
+ * Emitted on user input (mirrors native input event).
55
+ *
56
+ * @param {CustomEvent} event - The native input event from bl-switch.
57
+ */
58
+ input: [event: CustomEvent];
59
+ }>();
60
+
61
+ onMounted(() => {
62
+ loadBaklavaResources();
63
+ });
64
+ </script>
65
+
66
+ <template>
67
+ <bl-switch
68
+ v-bind="{
69
+ ...props,
70
+ checked: props.checked === true ? true : props.checked === false ? false : undefined,
71
+ disabled: props.disabled === true ? true : undefined,
72
+ }"
73
+ @bl-switch-toggle="
74
+ emit('change', $event);
75
+ emit('update:checked', $event.detail);
76
+ "
77
+ >
78
+ <slot>{{ label }}</slot>
79
+ </bl-switch>
80
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as BvSwitch } from "./Switch.vue";
2
+ export type { SwitchProps } from "./switch.types";
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Props for the Switch component.
3
+ */
4
+ export interface SwitchProps {
5
+ /** Checked state. Use with v-model:checked */
6
+ checked?: boolean;
7
+ /** Whether the switch is disabled */
8
+ disabled?: boolean;
9
+ /** Label for the switch */
10
+ label?: string;
11
+ /** Switch size (small, medium, large) */
12
+ size?: string;
13
+ }