Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5084bce
feat: Add badge label support to IconButton component
navidshad Aug 31, 2025
e5dce71
chore(release): 1.17.0-dev.36 [skip ci]
semantic-release-bot Sep 1, 2025
41ccd32
feat: #86eunvbgj Add InputGroup component with Storybook documentation
navidshad Sep 1, 2025
dc90f6f
feat: #86eunvbgj Enhance Input and TextArea components for InputGroup…
navidshad Sep 8, 2025
40ee215
feat: #86eunvbgj Enhance InputGroup and related components for impro…
navidshad Sep 8, 2025
dcb6d69
feat: #86eunvbgj Enhance Button and Input components for InputGroup c…
navidshad Sep 8, 2025
0593109
feat: #86eunvbgj Enhance InputGroup and related components for improv…
navidshad Sep 8, 2025
abff417
feat: #86eunvbgj Enhance Button and InputGroup integration with new b…
navidshad Sep 8, 2025
9023937
feat: Enhance Button component with focus styling and loading state h…
navidshad Sep 8, 2025
dab9956
feat: #86eunvbgj Refactor InputGroup and Button components for improv…
navidshad Sep 8, 2025
8029f74
feat: #86eunvbgj Enhance InputGroup and related components with focus…
navidshad Sep 9, 2025
4df36d0
fix: #86eunvbgj Improve error handling and styling in InputGroup and …
navidshad Sep 9, 2025
e50d144
feat: Update Component Development Guidelines to include InputGroup i…
navidshad Sep 9, 2025
74976d8
refactor: #86eunvbgj Update InputGroup and related components to mana…
navidshad Sep 9, 2025
49a570a
fix: #86eunvbgj Update Button accessibility test and add InputGroup t…
navidshad Sep 9, 2025
dd1f4a7
Merge pull request #73 from codebridger/CU-86eunvbgj_Implement-the-In…
navidshad Sep 9, 2025
e6c0cf8
chore(release): 1.17.0-dev.37 [skip ci]
semantic-release-bot Sep 9, 2025
0cd402d
Merge remote-tracking branch 'origin/main' into dev
navidshad Sep 9, 2025
6541a5e
Merge branch 'dev' of https://github.com/tiny-ideas-ir/lib-vue-compon…
navidshad Sep 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .cursor/rules/Component-development-guidelines.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,18 @@ alwaysApply: false
- Support validation states with error styling
- Include proper labels and helper text

#### InputGroup Integration
- **MANDATORY**: All form input components must support InputGroup integration
- Import `useInputGroup` composable and destructure required properties
- Hide individual labels and error messages when `isInInputGroup` is true
- Use `props.error` directly for error state (InputGroup passes this via props)
- Apply conditional class binding: InputGroup classes when in group, default when standalone
- Implement focus/blur event handlers for border management
- Use `h-10` height and `flex-1` width for form inputs in InputGroup
- Use content width for buttons in InputGroup
- Apply `!important` to error borders for proper CSS specificity
- Exclude TextArea from InputGroup due to height constraints

#### Modal Components
- Use Headless UI Dialog components
- Support custom triggers via slots
Expand Down Expand Up @@ -189,4 +201,5 @@ alwaysApply: false
- **RTL Support**: Check directional styling uses logical properties
- **Accessibility**: Always consider accessibility when creating/modifying components
- **Pattern Consistency**: Follow established patterns from existing components
- **InputGroup Compliance**: Ensure all new form components support InputGroup integration
- **Code Examples**: Provide complete, runnable code examples
29 changes: 29 additions & 0 deletions CHANGELOG-DEV.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
# [1.17.0-dev.37](https://github.com/codebridger/lib-vue-components/compare/dev-1.17.0-dev.36...dev-1.17.0-dev.37) (2025-09-09)


### Bug Fixes

* [#86](https://github.com/codebridger/lib-vue-components/issues/86)eunvbgj Improve error handling and styling in InputGroup and related components ([4df36d0](https://github.com/codebridger/lib-vue-components/commit/4df36d014f7aee577c32406daf84e25370b8536c))
* [#86](https://github.com/codebridger/lib-vue-components/issues/86)eunvbgj Update Button accessibility test and add InputGroup tests ([49a570a](https://github.com/codebridger/lib-vue-components/commit/49a570a351777c9165fa9ef4b0fda272b2e23331))


### Features

* [#86](https://github.com/codebridger/lib-vue-components/issues/86)eunvbgj Enhance InputGroup and related components for improved styling and functionality ([40ee215](https://github.com/codebridger/lib-vue-components/commit/40ee215e904beacb2fdc36dafd74b624aeb398b7))
* [#86](https://github.com/codebridger/lib-vue-components/issues/86)eunvbgj Add InputGroup component with Storybook documentation ([41ccd32](https://github.com/codebridger/lib-vue-components/commit/41ccd326aeed2fbce0cb58853d21ffc66385d470))
* [#86](https://github.com/codebridger/lib-vue-components/issues/86)eunvbgj Enhance Button and Input components for InputGroup consistency ([dcb6d69](https://github.com/codebridger/lib-vue-components/commit/dcb6d69bf9234ea3f92b7869939eab80306eb91c))
* [#86](https://github.com/codebridger/lib-vue-components/issues/86)eunvbgj Enhance Button and InputGroup integration with new button styling ([abff417](https://github.com/codebridger/lib-vue-components/commit/abff417b5f4491ace084eda7e72780878c8fc1da))
* [#86](https://github.com/codebridger/lib-vue-components/issues/86)eunvbgj Enhance Input and TextArea components for InputGroup integration ([dc90f6f](https://github.com/codebridger/lib-vue-components/commit/dc90f6f4e01c6726cebb7cbf55ddab3254278d57))
* [#86](https://github.com/codebridger/lib-vue-components/issues/86)eunvbgj Enhance InputGroup and related components for improved styling and consistency ([0593109](https://github.com/codebridger/lib-vue-components/commit/05931096a7e87de5c55193328b741c9d911289d5))
* [#86](https://github.com/codebridger/lib-vue-components/issues/86)eunvbgj Enhance InputGroup and related components with focus management and border styling ([8029f74](https://github.com/codebridger/lib-vue-components/commit/8029f742c8499c60c82d19b2203436edb160f79c))
* [#86](https://github.com/codebridger/lib-vue-components/issues/86)eunvbgj Refactor InputGroup and Button components for improved styling and consistency ([dab9956](https://github.com/codebridger/lib-vue-components/commit/dab9956eecf59ab2b365e57b88e9e08d58d8e2e3))
* Enhance Button component with focus styling and loading state handling ([9023937](https://github.com/codebridger/lib-vue-components/commit/9023937a494c30f5ee9f1f8ca89ecbc6913176ad))
* Update Component Development Guidelines to include InputGroup integration requirements ([e50d144](https://github.com/codebridger/lib-vue-components/commit/e50d1448e4c1fce202c21af2732629e68c67a276))

# [1.17.0-dev.36](https://github.com/codebridger/lib-vue-components/compare/dev-1.17.0-dev.35...dev-1.17.0-dev.36) (2025-09-01)


### Features

* Add badge label support to IconButton component ([5084bce](https://github.com/codebridger/lib-vue-components/commit/5084bce5f7048beacbc1efee050864467b958155))

# [1.17.0-dev.35](https://github.com/codebridger/lib-vue-components/compare/dev-1.17.0-dev.34...dev-1.17.0-dev.35) (2025-08-30)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,4 @@
"vitest": "^3.2.4",
"vue-tsc": "^0.40.4"
}
}
}
160 changes: 160 additions & 0 deletions src/composables/use-input-group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { inject, computed, getCurrentInstance, ref } from "vue";

interface InputGroupContext {
isRtl: boolean;
isDarkMode: boolean;
error: boolean;
disabled: boolean;
removeRightBorder?: boolean;
}

export function useInputGroup() {
const inputGroupContext = inject<InputGroupContext | null>(
"inputGroupContext",
null
);

if (!inputGroupContext) {
return {
isInInputGroup: false,
position: null,
inputGroupClasses: computed(() => []),
inputGroupItemClasses: computed(() => []),
inputGroupButtonClasses: computed(() => []),
inputGroupBorderClasses: "",
};
}

const instance = getCurrentInstance();
const position = instance?.vnode?.props?.["data-input-group-position"] as
| string
| null;
const removeRightBorder = instance?.vnode?.props?.[
"data-input-group-remove-right-border"
] as boolean | null;
const childIndex = instance?.vnode?.props?.["data-input-group-index"] as
| number
| null;

// Track focus state for this specific child
const isFocused = ref(false);

const inputGroupClasses = computed(() => {
const classes: string[] = [];
const { isRtl, error, disabled } = inputGroupContext;

// Base classes for input group children (replaces form-input)
classes.push(
"border px-4 py-2 text-sm font-semibold text-black dark:text-white-dark focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary"
);

if (error) {
classes.push("!border-red-500");
} else {
classes.push("border-gray-300 dark:border-gray-600");
}

// Don't handle disabled styling here - let child components handle their own disabled styling
classes.push("bg-white dark:bg-gray-800");

// Position-based styling - with gaps, all elements get full borders and radius
if (position) {
if (position === "first") {
classes.push(isRtl ? "rounded-r-md" : "rounded-l-md");
} else if (position === "last") {
classes.push(isRtl ? "rounded-l-md" : "rounded-r-md");
} else if (position === "only") {
classes.push("rounded-md");
} else {
// Middle elements - no radius
classes.push("rounded-none");
}
}

// Border removal for seamless connection - but not when focused
if (removeRightBorder && !isFocused.value) {
classes.push("border-r-0");
}

return classes;
});

// Additional classes for InputGroupItem (non-form elements)
const inputGroupItemClasses = computed(() => {
const classes = [...inputGroupClasses.value];

// Add default styling for non-form elements
classes.push("bg-gray-100 dark:bg-gray-700");
classes.push(
"flex items-center px-3 text-sm font-medium text-gray-700 dark:text-gray-300"
);

return classes;
});

// Classes for buttons in InputGroup (no flex-1, different styling)
const inputGroupButtonClasses = computed(() => {
const classes: string[] = [];
const { isRtl, error, disabled } = inputGroupContext;

// Base classes for buttons in input group - only border and padding
classes.push(
"border px-4 py-2 focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary"
);

if (error) {
classes.push("!border-red-500");
} else if (disabled) {
classes.push("border-gray-300 dark:border-gray-600");
} else {
// Don't set border color when not disabled or error - let button color classes handle it
// But we still need a base border for the group styling
classes.push("border-gray-300 dark:border-gray-600");
}

// Don't handle disabled styling here - let child components handle their own disabled styling
// Don't set background color - let button color classes handle it

// Position-based styling - with gaps, all elements get full borders and radius
if (position) {
if (position === "first") {
classes.push(isRtl ? "rounded-r-md" : "rounded-l-md");
} else if (position === "last") {
classes.push(isRtl ? "rounded-l-md" : "rounded-r-md");
} else if (position === "only") {
classes.push("rounded-md");
} else {
// Middle elements - no radius
classes.push("rounded-none");
}
}

// Border removal for seamless connection - but not when focused
if (removeRightBorder && !isFocused.value) {
classes.push("border-r-0");
}

return classes;
});

// Focus event handlers
const handleFocus = () => {
isFocused.value = true;
};

const handleBlur = () => {
isFocused.value = false;
};

return {
isInInputGroup: true,
position,
inputGroupClasses,
inputGroupItemClasses,
inputGroupButtonClasses,
inputGroupBorderClasses: inject<string>("inputGroupBorderClasses", ""),
context: inputGroupContext,
handleFocus,
handleBlur,
};
}
Loading