-
Notifications
You must be signed in to change notification settings - Fork 7.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add icon-picker component #4832
Conversation
|
WalkthroughThe pull request introduces several changes across multiple files, primarily adding new components and functionalities related to icon management and selection. Key updates include the addition of the Changes
Assessment against linked issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Outside diff range and nitpick comments (11)
packages/effects/hooks/src/use-pagination.ts (1)
13-34
: Consider enhancing the API with additional pagination metadata.The hook could provide more useful information to consumers.
Consider adding these computed properties:
export function usePagination<T = any>(list: Ref<T[]>, pageSize: number) { // ... existing code ... + const isFirstPage = computed(() => currentPage.value === 1); + const isLastPage = computed(() => + currentPage.value === unref(totalPages) + ); + const pageCount = computed(() => + Math.ceil(unref(list).length / unref(pageSizeRef)) + ); return { setCurrentPage, getTotal, setPageSize, getPaginationList, + isFirstPage, + isLastPage, + pageCount, + currentPage: readonly(currentPage), }; }packages/effects/common-ui/package.json (1)
31-31
: Sort dependencies alphabetically.The dependencies should be ordered alphabetically for better maintainability.
Apply this diff to fix the ordering:
"@vben/constants": "workspace:*", + "@vben/hooks": "workspace:*", "@vben/icons": "workspace:*", "@vben/locales": "workspace:*", "@vben/types": "workspace:*", - "@vben/hooks": "workspace:*",🧰 Tools
🪛 GitHub Check: Lint (ubuntu-latest)
[failure] 31-31:
Expected object keys to be in ascending order. '@vben/hooks' should be before '@vben/types'packages/@core/ui-kit/shadcn-ui/src/components/button/icon-button.vue (2)
25-25
: LGTM: Default tooltip delay is reasonable.The 200ms default delay is a good choice for tooltip behavior. Consider making this value configurable via a global theme configuration for consistency across the application.
47-51
: Consider reducing template code duplication.While the tooltip delay implementation is correct, there's an opportunity to reduce code duplication by restructuring the template.
Consider this alternative structure that avoids duplicating the VbenButton code:
- <VbenButton - v-if="!showTooltip" - :class="cn('rounded-full', props.class)" - :disabled="disabled" - :variant="variant" - size="icon" - @click="onClick" - > - <slot></slot> - </VbenButton> - - <VbenTooltip - v-else - :delay-duration="tooltipDelayDuration" - :side="tooltipSide" - > + <template v-if="showTooltip"> + <VbenTooltip + :delay-duration="tooltipDelayDuration" + :side="tooltipSide" + > + <template #trigger> + <VbenButton + :class="cn('rounded-full', props.class)" + :disabled="disabled" + :variant="variant" + size="icon" + @click="onClick" + > + <slot></slot> + </VbenButton> + </template> + <slot v-if="slots.tooltip" name="tooltip"> </slot> + <template v-else> + {{ tooltip }} + </template> + </VbenTooltip> + </template> + <template v-else> <template #trigger> <VbenButton :class="cn('rounded-full', props.class)" @@ -62,11 +62,8 @@ > <slot></slot> </VbenButton> - </template> - <slot v-if="slots.tooltip" name="tooltip"> </slot> - <template v-else> - {{ tooltip }} - </template> - </VbenTooltip> + </template>This refactoring:
- Reduces code duplication
- Makes the conditional logic clearer
- Maintains the same functionality
playground/src/views/demos/features/icons/icon-picker.vue (4)
1-9
: Consider organizing imports by category.While all imports are necessary, consider organizing them in a more structured way:
- Vue core imports
- External library imports (ant-design-vue)
- Internal library imports (@vben/*)
- Local imports
<script lang="ts" setup> import { ref } from 'vue'; -import { IconPicker } from '@vben/common-ui'; -import { listIcons } from '@vben/icons'; - import { Input } from 'ant-design-vue'; +import { IconPicker } from '@vben/common-ui'; +import { listIcons } from '@vben/icons'; + import iconsData from './icons.data';
11-21
: Add JSDoc documentation for all props and improve type safety.While the interface is well-structured, consider these improvements:
- Add JSDoc documentation for all properties to improve maintainability
- Add validation for pageSize
- Use more specific type for width property
export interface Props { + /** + * Whether to show clear button + * @default true + */ allowClear?: boolean; + /** + * Number of icons to display per page + * @default 36 + * @minimum 1 + */ pageSize?: number; /** * 可以通过prefix获取系统中使用的图标集 */ prefix?: string; + /** + * Whether the input is read-only + * @default false + */ readonly?: boolean; + /** + * Selected icon value + * @default '' + */ value?: string; - width?: string; + /** + * Width of the picker + * @default '100%' + */ + width?: `${number}px` | `${number}%`; }
28-35
: Consider adding prop validation.While the defaults are sensible, consider adding runtime validation for better error handling:
-const props = withDefaults(defineProps<Props>(), { +const props = withDefaults(defineProps<Props>({ + pageSize: { + type: Number, + default: 36, + validator: (value: number) => value > 0 + } +}), { allowClear: true, - pageSize: 36, prefix: '', readonly: false, value: '', width: '100%', });
62-82
: Enhance accessibility for icon picker input.Consider adding ARIA attributes and keyboard navigation support:
<Input v-model:value="currentSelect" :allow-clear="props.allowClear" :readonly="props.readonly" :style="{ width }" class="cursor-pointer" placeholder="点击选中图标" + role="combobox" + aria-label="Icon picker" + aria-expanded="false" + @keydown.enter="triggerPopover" @click="triggerPopover" >playground/src/views/demos/features/icons/index.vue (1)
63-73
: Consider enhancing the IconPicker implementationWhile the basic implementation is good, consider these improvements for better usability:
- Add two-way binding to track selected icons
- Implement event handlers for icon selection
- Add loading states and error handling
Here's a suggested implementation:
- <IconPicker width="300px" /> + <IconPicker + v-model:value="selectedIconify" + width="300px" + @select="handleIconSelect" + @error="handleError" + /> - <IconPicker prefix="svg" width="300px" /> + <IconPicker + v-model:value="selectedSvg" + prefix="svg" + width="300px" + @select="handleSvgIconSelect" + @error="handleError" + />Add corresponding script section:
const selectedIconify = ref(''); const selectedSvg = ref(''); const handleIconSelect = (icon: string) => { console.log('Selected Iconify icon:', icon); }; const handleSvgIconSelect = (icon: string) => { console.log('Selected SVG icon:', icon); }; const handleError = (error: Error) => { console.error('Icon picker error:', error); };packages/effects/common-ui/src/components/icon-picker/icon-picker.vue (2)
25-26
: Translate comment to English for consistencyThe comment on lines 25-26 is in Chinese. For consistency and to aid understanding for all contributors, consider translating it to English.
Apply this diff to translate the comment:
/** - * 图标列表 + * Icon list */
70-74
: EnsurechangeOpenState
toggles the popover correctlyThe
changeOpenState
method triggers a click event onrefTrigger
to toggle the popover's open state. This approach could lead to unexpected side effects if additional click handlers are attached to the trigger element. Consider using the popover's API to control its open state directly for clearer intent and better maintainability.Apply this diff to use the popover's
isOpen
state:// Add a ref to the popover +const popoverRef = ref(); // Update the template to reference the popover -<VbenPopover +<VbenPopover + ref="popoverRef" :content-props="{ align: 'end', alignOffset: -11, sideOffset: 8 }" content-class="p-0 py-4" > // Modify the changeOpenState method const changeOpenState = () => { - if (refTrigger.value) { - refTrigger.value.click(); - } + if (popoverRef.value) { + popoverRef.value.isOpen = !popoverRef.value.isOpen; + } };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
packages/@core/base/icons/src/index.ts
(1 hunks)packages/@core/base/icons/src/lucide.ts
(2 hunks)packages/@core/ui-kit/shadcn-ui/src/components/button/icon-button.vue
(2 hunks)packages/effects/common-ui/package.json
(1 hunks)packages/effects/common-ui/src/components/icon-picker/icon-picker.vue
(1 hunks)packages/effects/common-ui/src/components/icon-picker/index.ts
(1 hunks)packages/effects/common-ui/src/components/index.ts
(1 hunks)packages/effects/hooks/src/index.ts
(1 hunks)packages/effects/hooks/src/use-pagination.ts
(1 hunks)playground/src/views/demos/features/icons/icon-picker.vue
(1 hunks)playground/src/views/demos/features/icons/icons.data.ts
(1 hunks)playground/src/views/demos/features/icons/index.vue
(3 hunks)
✅ Files skipped from review due to trivial changes (2)
- packages/effects/common-ui/src/components/icon-picker/index.ts
- playground/src/views/demos/features/icons/icons.data.ts
🧰 Additional context used
🪛 GitHub Check: Lint (ubuntu-latest)
packages/effects/common-ui/package.json
[failure] 31-31:
Expected object keys to be in ascending order. '@vben/hooks' should be before '@vben/types'
🔇 Additional comments (13)
packages/effects/hooks/src/index.ts (1)
4-4
: LGTM! Verify module existence.
The export follows the established pattern and integrates well with other hook exports.
Let's verify the module existence and potential circular dependencies:
✅ Verification successful
Module exists and no circular dependencies detected ✅
The verification confirms:
use-pagination.ts
module exists at the expected location- Only
index.ts
imports fromuse-pagination
, indicating no circular dependencies
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify that the use-pagination module exists and check for potential circular dependencies
# Check if the module exists
fd -t f "use-pagination.ts" packages/effects/hooks/src
# Look for any circular import patterns
rg -l "from.*use-pagination" packages/effects/hooks/src
Length of output: 193
packages/@core/base/icons/src/index.ts (1)
7-12
: LGTM! The export addition is well-structured.
The addition of listIcons
to the exports is appropriate for implementing the icon-picker feature, as it provides the necessary functionality to enumerate available icons.
Let's verify that this export is being used by the new icon-picker component:
✅ Verification successful
The initial results show listIcons
is imported from '@vben/icons' but we need to verify if this is the correct import path and matches our package name, as the export we're reviewing is in '@core/base/icons'.
We need to verify if @vben/icons is correctly aliased to our @vben-core/icons package, as there seems to be a discrepancy between the package name and the import path.
The results show there's a bridge package @vben/icons
that depends on our core package @vben-core/icons
. We need to verify how the listIcons
export is being re-exported through this bridge package to ensure the chain of exports is correct.
We need to trace how the listIcons
export flows through the bridge package's directory structure since we see it exports from './iconify/index.js' and './svg/index.js'.
The export chain is correctly implemented
The verification confirms that:
- The core package
@vben-core/icons
exportslistIcons
from '@iconify/vue' - The bridge package
@vben/icons
correctly re-exports everything from '@vben-core/icons' viaexport * from '@vben-core/icons'
- The icon-picker component correctly imports
listIcons
from '@vben/icons' - The export is being actively used in the icon-picker component
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the usage of listIcons in the icon-picker component
# Expected: Find usage of listIcons in the new icon-picker component
# Search for icon-picker component files
echo "Searching for icon-picker component files..."
fd -t f "icon-picker"
# Search for usage of listIcons
echo "Searching for listIcons usage..."
rg "listIcons" -A 3
Length of output: 1161
Script:
#!/bin/bash
# Let's verify the import path in the icon-picker component
# to ensure it's correctly importing from our package
# First, check the package.json to confirm our package name
echo "Checking package name in core icons package.json..."
cat packages/@core/base/icons/package.json
# Then check the actual import statement in the component
echo "\nChecking import statement context..."
rg -B 2 -A 2 "@vben/icons" playground/src/views/demos/features/icons/icon-picker.vue
Length of output: 1371
Script:
#!/bin/bash
# Let's check the package aliases in the project configuration
# to understand the mapping between @vben/icons and our package
# Check for package aliases in common configuration files
echo "Checking for package aliases..."
fd -t f "vite.config|tsconfig|package" -e json -e ts | xargs rg "@vben/icons|@vben-core/icons" -A 3
# Also check the root package.json for workspace configurations
echo "\nChecking root package.json..."
cat package.json
Length of output: 8441
Script:
#!/bin/bash
# Let's check the packages/icons directory since it appears to be the bridge package
echo "Checking the content of packages/icons/src..."
cat packages/icons/src/index.ts
# Also check if there are any re-exports of listIcons
echo "\nChecking for re-exports of listIcons in packages/icons..."
rg -B 2 -A 2 "export.*listIcons" packages/icons/
Length of output: 382
Script:
#!/bin/bash
# Let's check the iconify directory since it's being exported
echo "Checking iconify/index.js content..."
cat packages/icons/src/iconify/index.ts
# Also check the svg directory
echo "\nChecking svg/index.js content..."
cat packages/icons/src/svg/index.ts
# Check if there are any other files in iconify directory that might re-export listIcons
echo "\nListing files in iconify directory..."
ls -la packages/icons/src/iconify/
Length of output: 1679
packages/effects/common-ui/src/components/index.ts (1)
3-3
: LGTM! Verify the icon-picker module.
The export statement follows the established pattern and aligns with the PR objectives.
Let's verify the icon-picker module exists and exports the expected component:
✅ Verification successful
Let me check the actual exports from the index.ts file to ensure it's exporting the component correctly.
Icon picker module is properly implemented and exported
The module structure is correct with:
- A properly implemented Vue component using Composition API
- Correct default export in
icon-picker.vue
- Proper re-export in the barrel file
index.ts
- Complete implementation including pagination and icon selection functionality
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the icon-picker module structure and exports
# Test 1: Check if the icon-picker directory exists
fd -t d "icon-picker$" packages/effects/common-ui/src/components
# Test 2: Check for the component file
fd -t f "icon-picker.(vue|tsx)$" packages/effects/common-ui/src/components
# Test 3: Check for the barrel file
fd -t f "index.(ts|js)$" packages/effects/common-ui/src/components/icon-picker
# Test 4: Examine the exports
rg -l "export.*IconPicker" packages/effects/common-ui/src/components/icon-picker
Length of output: 558
Script:
#!/bin/bash
# Check the actual exports in the index.ts file
cat packages/effects/common-ui/src/components/icon-picker/index.ts
# Also verify the component implementation exists in the Vue file
cat packages/effects/common-ui/src/components/icon-picker/icon-picker.vue
Length of output: 3784
packages/@core/base/icons/src/lucide.ts (1)
30-30
: LGTM! New icon exports maintain consistency.
The added Grip
and Package2
icons follow the established export pattern and maintain alphabetical ordering.
Let's verify these icons exist in the lucide-vue-next package:
Also applies to: 44-44
✅ Verification successful
LGTM! Icons are properly configured and available.
The verification confirms:
lucide-vue-next
is properly listed as a dependency in the relevant packages- Both
Grip
andPackage2
icons are present in the exports list atpackages/@core/base/icons/src/lucide.ts
- The icons follow the established export pattern and alphabetical ordering
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the new icons exist in package.json dependencies
# and are exported by lucide-vue-next
# Test 1: Check if lucide-vue-next is listed in dependencies
echo "Checking package dependencies..."
cat package.json | jq -r '.dependencies["lucide-vue-next"] // .devDependencies["lucide-vue-next"]'
# Test 2: Search for icon imports in node_modules
# Note: This is a basic check as build artifacts aren't available in the sandbox
echo "Searching for icon exports..."
fd -t f "index.*" node_modules/lucide-vue-next -x grep -l "export.*Grip.*Package2" {} \;
Length of output: 459
Script:
#!/bin/bash
# Let's try a different approach to verify the icons
# 1. Check package.json in the base directory and parent directories
echo "Checking package.json files..."
fd -t f "package.json" . packages/@core/base -x cat {} \;
# 2. Look for actual icon imports in the codebase
echo -e "\nChecking icon usage..."
rg -l "import.*\{.*(?:Grip|Package2).*\}.*from.*lucide" --type ts
# 3. Check if these icons are used in components
echo -e "\nChecking component usage..."
rg "(?:Grip|Package2)" --type vue --type ts -l
Length of output: 52329
Script:
#!/bin/bash
# Let's verify if lucide-vue-next is properly configured and check icon usage
# 1. Check if lucide-vue-next is a direct dependency
echo "Checking lucide-vue-next dependency..."
rg '"lucide-vue-next"' --type json
# 2. Look for icon imports and usage with more flexible patterns
echo -e "\nChecking icon imports and usage..."
rg "(?:Grip|Package2)" --type ts -A 2 -B 2
# 3. Check the actual icon export file
echo -e "\nChecking icon exports..."
rg "export.*(?:Grip|Package2)" packages/@core/base/icons/src/lucide.ts
Length of output: 1121
packages/effects/hooks/src/use-pagination.ts (1)
1-2
: LGTM! Imports are clean and necessary.
packages/effects/common-ui/package.json (1)
31-31
: LGTM! Verify the workspace dependency.
The addition of @vben/hooks
as a workspace dependency is appropriate for implementing the pagination functionality in the icon-picker component.
Let's verify the workspace package existence and its exports:
✅ Verification successful
Workspace dependency verified and correctly used
The verification confirms:
@vben/hooks
exists as a workspace package and is used across multiple packages- The package exports
usePagination
hook frompackages/effects/hooks/src/use-pagination.ts
- The dependency is correctly referenced by other packages using
workspace:*
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify @vben/hooks workspace package and its pagination hook
# Test 1: Check if the hooks package exists
fd -t f "package.json" -x grep -l "@vben/hooks"
# Test 2: Verify the pagination hook implementation
rg -t ts "export.*usePagination" packages/effects/hooks
Length of output: 496
🧰 Tools
🪛 GitHub Check: Lint (ubuntu-latest)
[failure] 31-31:
Expected object keys to be in ascending order. '@vben/hooks' should be before '@vben/types'
packages/@core/ui-kit/shadcn-ui/src/components/button/icon-button.vue (1)
17-17
: LGTM: Props interface addition is well-structured.
The new tooltipDelayDuration
prop is properly typed as an optional number and follows the existing naming conventions.
playground/src/views/demos/features/icons/icon-picker.vue (1)
23-26
: LGTM!
Good use of defineOptions
to prevent inheriting FormItem attributes, with clear documentation.
playground/src/views/demos/features/icons/index.vue (3)
20-21
: LGTM: Clean import of IconPicker component
The import statement is properly placed and follows the component organization pattern.
50-50
: LGTM: Consistent spacing
Adding margin-bottom improves the visual hierarchy and spacing between cards.
63-73
: Verify IconPicker documentation
Please ensure that the IconPicker component is properly documented with its available props, events, and usage examples.
Let's check if documentation exists:
✅ Verification successful
Documentation exists in the component implementation
The IconPicker component is well-documented within its implementation. Here are the available props and events:
Props:
value
(string, optional): Selected icon value, defaults to ''pageSize
(number, optional): Number of icons per page, defaults to 36icons
(string[], optional): Array of icon identifiers, defaults to []
Events:
change
: Emitted when an icon is selectedupdate:value
: v-model support for the selected value
The component is also documented in the general icons documentation which shows different icon usage approaches in the project. No additional documentation is needed.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for documentation files related to IconPicker
fd -e md -e mdx "icon-picker|icons" --exec cat {} \;
# Search for documentation in component file
rg -A 10 "^/\*\*|^///" "./playground/src/views/demos/features/icons/icon-picker.vue"
Length of output: 3728
Script:
#!/bin/bash
# Let's check the IconPicker component implementation to find props and events
rg -A 20 "IconPicker" ./playground/src/components/
# Also check if there's a dedicated component file for IconPicker
fd "icon-picker" -t f
# Let's also check for any TypeScript definitions that might document the component
fd -e ts -e d.ts "icon-picker"
Length of output: 300
Script:
#!/bin/bash
# Let's check the actual implementation of IconPicker component
cat packages/effects/common-ui/src/components/icon-picker/icon-picker.vue
# Also check for any props or types definitions in the same directory
rg -t ts "interface|type|Props" packages/effects/common-ui/src/components/icon-picker/
Length of output: 3745
packages/effects/common-ui/src/components/icon-picker/icon-picker.vue (2)
144-144
: Verify the availability of the $t
function
The use of {{ $t('common.noData') }}
suggests reliance on an internationalization plugin like Vue I18n. Ensure that the $t
function is available in the component's context to prevent runtime errors when internationalization is not set up.
If internationalization is not intended, consider replacing it with a plain string:
- <div>{{ $t('common.noData') }}</div>
+ <div>No data available</div>
85-85
: Safety check for displaying user-provided icons
When rendering icons based on user-provided input, ensure that the icon data is sanitized to prevent potential security risks like XSS attacks. Although the icons come from a predefined list, adding a safety check reinforces security.
[security]
Consider validating the icon name before rendering:
<VbenIcon :icon="currentSelect || Grip" class="size-6" />
+<!-- Add a computed property to validate the icon -->
+const safeCurrentSelect = computed(() =>
+ props.icons.includes(currentSelect.value) ? currentSelect.value : Grip
+);
+
+<!-- Update the template -->
+<VbenIcon :icon="safeCurrentSelect" class="size-6" />
packages/effects/common-ui/src/components/icon-picker/icon-picker.vue
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (6)
packages/effects/common-ui/package.json (1)
30-30
: Consider reordering dependencies alphabetically.To maintain consistency with the project's style, consider reordering the dependencies alphabetically.
- "@vben/locales": "workspace:*", "@vben/hooks": "workspace:*", + "@vben/locales": "workspace:*",🧰 Tools
🪛 GitHub Check: Lint (ubuntu-latest)
[failure] 30-30:
Expected object keys to be in ascending order. '@vben/hooks' should be before '@vben/locales'playground/src/views/demos/features/icons/icon-picker.vue (3)
11-35
: Add JSDoc comments for all props.While the
prefix
prop is well documented, other props would benefit from similar documentation to improve component API clarity.Add documentation for remaining props:
export interface Props { + /** + * Whether to show clear button + * @default true + */ allowClear?: boolean; + /** + * Number of icons to display per page + * @default 36 + */ pageSize?: number; /** * 可以通过prefix获取系统中使用的图标集 */ prefix?: string; + /** + * Whether the input is read-only + * @default false + */ readonly?: boolean; + /** + * Selected icon value + * @default '' + */ value?: string; + /** + * Width of the input + * @default '100%' + */ width?: string; }
40-56
: Enhance error handling and logging.While the error handling is good, the warning message could be more informative for debugging purposes.
Consider enhancing the error handling:
const currentList = computed(() => { try { if (props.prefix) { const icons = listIcons('', props.prefix); if (icons.length === 0) { - console.warn(`No icons found for prefix: ${props.prefix}`); + console.warn( + `No icons found for prefix: ${props.prefix}. ` + + 'Please verify the prefix is correct and icons are registered.' + ); } return icons; } else { const prefix = iconsData.prefix; return iconsData.icons.map((icon) => `${prefix}:${icon}`); } } catch (error) { - console.error('Failed to load icons:', error); + console.error( + `Failed to load icons${props.prefix ? ` for prefix ${props.prefix}` : ''}: `, + error instanceof Error ? error.message : error + ); return []; } });
67-87
: Add ARIA labels for better accessibility.The input component should have proper ARIA labels to improve accessibility for screen readers.
Add aria-label to the input:
<Input v-model:value="currentSelect" :allow-clear="props.allowClear" :readonly="props.readonly" :style="{ width }" class="cursor-pointer" placeholder="点击选中图标" + aria-label="Icon selector" @click="triggerPopover" >
packages/effects/hooks/src/use-pagination.ts (2)
17-20
: Simplify the pagination logic by removing the conditional check.The current conditional check is unnecessary because
list.slice(offset, offset + pageSize)
will return elements up to the end of the array even ifoffset + pageSize
exceedslist.length
. Simplifying the code improves readability without affecting functionality.Apply this diff to simplify the code:
- const ret = - offset + pageSize >= list.length - ? list.slice(offset) - : list.slice(offset, offset + pageSize); - return ret; + return list.slice(offset, offset + pageSize);
56-57
: Specify explicit return type for theusePagination
function.Adding an explicit return type enhances type safety and improves code maintainability by making it clear what the function returns.
Consider defining an interface for the return type and applying it:
interface UsePaginationResult<T> { setCurrentPage: (page: number) => void; setPageSize: (pageSize: number) => void; getTotal: ComputedRef<number>; getPaginationList: ComputedRef<T[]>; } export function usePagination<T = any>(list: Ref<T[]>, pageSize: number): UsePaginationResult<T> { // existing code }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (4)
packages/effects/common-ui/package.json
(1 hunks)packages/effects/common-ui/src/components/icon-picker/icon-picker.vue
(1 hunks)packages/effects/hooks/src/use-pagination.ts
(1 hunks)playground/src/views/demos/features/icons/icon-picker.vue
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/effects/common-ui/src/components/icon-picker/icon-picker.vue
🧰 Additional context used
🪛 GitHub Check: Lint (ubuntu-latest)
packages/effects/common-ui/package.json
[failure] 30-30:
Expected object keys to be in ascending order. '@vben/hooks' should be before '@vben/locales'
🔇 Additional comments (4)
packages/effects/common-ui/package.json (1)
30-30
: LGTM: Dependency addition is appropriate.
The addition of @vben/hooks
as a workspace dependency is well-aligned with the implementation of pagination functionality in the icon-picker component.
🧰 Tools
🪛 GitHub Check: Lint (ubuntu-latest)
[failure] 30-30:
Expected object keys to be in ascending order. '@vben/hooks' should be before '@vben/locales'
playground/src/views/demos/features/icons/icon-picker.vue (3)
1-10
: LGTM! Imports are well-organized.
The imports are properly structured with clear separation between framework, UI components, and local data dependencies.
58-64
: LGTM! Event handlers are well-implemented.
The event handlers are concise, focused, and use proper optional chaining for null safety.
4-4
: Verify IconPicker component interface.
Let's verify that the IconPicker component from @vben/common-ui exists and accepts all the props we're passing to it.
Also applies to: 78-84
✅ Verification successful
Let me try a different search strategy to verify the IconPicker component.
Let me try one more search focusing on the common-ui package and its IconPicker component:
Based on the current file's usage, let me try one final search to locate the component in the monorepo:
Let me check the actual implementation of the IconPicker component now that we found its location:
IconPicker component interface verification completed successfully
The component exists in packages/effects/common-ui
and accepts all the props being passed in the usage:
icons
(array of strings) - matches thecurrentList
computed prop being passedpageSize
(number) - matches the prop with default 36value
(string) - matches thecurrentSelect
being passed@change
event - matches thehandleChange
handler
The implementation is complete with proper TypeScript types, event handling, and UI components.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for IconPicker component definition
echo "Searching for IconPicker component definition..."
ast-grep --pattern 'export const IconPicker = defineComponent({
$$$
})'
# Search for IconPicker props interface
echo "Searching for IconPicker props interface..."
ast-grep --pattern 'interface IconPickerProps {
$$$
}'
Length of output: 338
Script:
#!/bin/bash
# Search for IconPicker in all files
echo "Searching for IconPicker files..."
fd IconPicker
# Search for IconPicker usage and definition patterns
echo "Searching for IconPicker patterns..."
rg -l "IconPicker" --type vue --type ts --type tsx
# Look for package dependencies
echo "Checking package dependencies..."
fd "package.json" --exec cat {} \; | grep -A 5 -B 5 "@vben/common-ui"
Length of output: 2279
Script:
#!/bin/bash
# Search specifically in the common-ui package
echo "Searching in common-ui package..."
fd . packages/common-ui -t f | grep -i iconpicker
# Search for IconPicker component content
echo "Searching IconPicker content..."
rg -t ts -t tsx "IconPicker" packages/common-ui -C 5
# Check the usage in the current file
echo "Checking current file usage..."
cat playground/src/views/demos/features/icons/icon-picker.vue
Length of output: 2351
Script:
#!/bin/bash
# Try to find the package in different possible locations
echo "Searching for IconPicker in possible monorepo locations..."
fd . -t f -e ts -e tsx -e vue | grep -i "common.*icon"
# Search for any IconPicker related files
echo "Searching for IconPicker content in all files..."
rg "IconPicker" -l --type-add 'vue:*.vue' --type-add 'tsx:*.tsx' --type vue --type tsx --type ts
# Check if it's in node_modules
echo "Checking node_modules for the package..."
fd . node_modules/@vben/common-ui -t f 2>/dev/null || echo "No node_modules found"
Length of output: 1200
Script:
#!/bin/bash
# Check the IconPicker component implementation
echo "Checking IconPicker component implementation..."
cat packages/effects/common-ui/src/components/icon-picker/icon-picker.vue
# Check the index file for exports
echo "Checking index file..."
cat packages/effects/common-ui/src/components/icon-picker/index.ts
Length of output: 4056
Description
feat: add icon-picker component
添加图标选择组件 fix: #4526
Type of change
Please delete options that are not relevant.
Checklist
Summary by CodeRabbit
Release Notes
New Features
listIcons
function for improved icon management.Grip
andPackage2
.IconPicker
component for user-friendly icon selection with pagination support.Enhancements
Dependencies
@vben/hooks
for enhanced functionality.These updates aim to improve user experience and flexibility in icon selection and management.