diff --git a/packages/__docs__/src/Icons/LucideIconsGallery.tsx b/packages/__docs__/src/Icons/LucideIconsGallery.tsx index 8dd0f5a335..1c593bad83 100644 --- a/packages/__docs__/src/Icons/LucideIconsGallery.tsx +++ b/packages/__docs__/src/Icons/LucideIconsGallery.tsx @@ -38,7 +38,6 @@ import { Modal } from '@instructure/ui-modal' import { SourceCodeEditor } from '@instructure/ui-source-code-editor' import * as LucideIcons from '@instructure/ui-icons-lucide' import { XInstUIIcon } from '@instructure/ui-icons-lucide' -import { Link } from '@instructure/ui-link' import { Flex } from '@instructure/ui-flex' // Get all exported Lucide icons (excluding utilities and types) @@ -65,7 +64,7 @@ function getUsageInfo(iconName: string) { const MyIcon = () => { return ( - <${iconName} size={24} /> + <${iconName} size={'2xl'} color='successColor'/> ) }` } @@ -290,24 +289,25 @@ const LucideIconsGallery = () => { -

- These icons use the pure Lucide API. See{' '} - - Lucide documentation - {' '} - for more details. -

diff --git a/packages/ui-avatar/package.json b/packages/ui-avatar/package.json index aa2d09bd9b..46be1388cb 100644 --- a/packages/ui-avatar/package.json +++ b/packages/ui-avatar/package.json @@ -26,7 +26,7 @@ "@babel/runtime": "^7.27.6", "@instructure/emotion": "workspace:*", "@instructure/shared-types": "workspace:*", - "@instructure/ui-icons": "workspace:*", + "@instructure/ui-icons-lucide": "workspace:*", "@instructure/ui-react-utils": "workspace:*", "@instructure/ui-view": "workspace:*" }, diff --git a/packages/ui-avatar/src/Avatar/README.md b/packages/ui-avatar/src/Avatar/README.md index adf861b4a6..9e1383032c 100644 --- a/packages/ui-avatar/src/Avatar/README.md +++ b/packages/ui-avatar/src/Avatar/README.md @@ -16,22 +16,22 @@ readonly: true
- - - - - - - + + + + + + + - - - - - - - + + + + + + +
``` @@ -46,16 +46,47 @@ type: example readonly: true --- - - - - - - - + + + + + + + ``` +### Using Lucide Icons + +Lucide icons in Avatar are automatically sized and colored according to the Avatar's `size` and `color` props, so manual adjustments are not needed on the icon itself. + +```js +--- +type: example +--- +
+ + + + + + + + + + + } /> + } /> + } /> + + + } /> + } /> + } /> + +
+``` + ### Size The `size` prop allows you to select from `xx-small`, `x-small`, `small`, `medium` _(default)_, `large`, `x-large`, and `xx-large`. Each size has predefined dimensions and typography scales. @@ -66,31 +97,31 @@ type: example ---
- - - - - - - + + + + + + + - - - - - - - + + + + + + + - } size="xx-small" /> - } size="x-small" /> - } size="small" /> - } size="medium" /> - } size="large" /> - } size="x-large" /> - } size="xx-large" /> + + + + + + +
``` @@ -105,22 +136,22 @@ type: example ---
- - - - - - - + + + + + + + - } name="Arthur C. Clarke" /> - } name="James Arias" color="accent2" /> - } name="Charles Kimball" color="accent3" /> - } name="Melissa Reed" color="accent4" /> - } name="Heather Wheeler" color="accent5" /> - } name="David Herbert" color="accent6" /> - } name="Isaac Asimov" color="accent1" /> + + + + + + +
``` @@ -135,22 +166,22 @@ type: example ---
- - - - - - - + + + + + + + - } name="Arthur C. Clarke" hasInverseColor /> - } name="James Arias" color="accent2" hasInverseColor /> - } name="Charles Kimball" color="accent3" hasInverseColor /> - } name="Melissa Reed" color="accent4" hasInverseColor /> - } name="Heather Wheeler" color="accent5" hasInverseColor /> - } name="David Herbert" color="accent6" hasInverseColor /> - } name="Isaac Asimov" color="accent1" hasInverseColor /> + + + + + + +
``` @@ -162,10 +193,10 @@ In case you need more control over the color, feel free to use the `themeOverrid type: example ---
- } themeOverride={{ accent1TextColor: '#efb410' }} /> - - } hasInverseColor themeOverride={{ textOnColor: 'lightblue', backgroundColor: 'black' }} /> - + + + +
``` @@ -179,14 +210,14 @@ type: example ---
Inline avatars: - - + + are displayed inline with text.
Block avatars: - - + + stack vertically.
@@ -202,7 +233,7 @@ type: example ---
- } showBorder="never" /> +
``` @@ -218,8 +249,7 @@ type: example } - + renderIcon={UsersInstUIIcon} /> Image takes priority over icon diff --git a/packages/ui-avatar/src/Avatar/__tests__/Avatar.test.tsx b/packages/ui-avatar/src/Avatar/__tests__/Avatar.test.tsx index 52ea7a4bdf..8b882a5c8d 100644 --- a/packages/ui-avatar/src/Avatar/__tests__/Avatar.test.tsx +++ b/packages/ui-avatar/src/Avatar/__tests__/Avatar.test.tsx @@ -28,7 +28,7 @@ import { runAxeCheck } from '@instructure/ui-axe-check' import '@testing-library/jest-dom' import Avatar from '../index' -import { IconGroupLine } from '@instructure/ui-icons' +import { HeartInstUIIcon } from '@instructure/ui-icons-lucide' describe('', () => { describe('for a11y', () => { @@ -78,14 +78,9 @@ describe('', () => { }) describe('when the renderIcon prop is provided', () => { - it('should display an svg passed', async () => { - const SomeIcon = () => ( - - - - ) + it('should display a Lucide icon when passed as component reference', async () => { const { container } = render( - + hello ) @@ -93,24 +88,40 @@ describe('', () => { expect(avatarSvg).toBeInTheDocument() }) - it('should display an InstUI icon passed', async () => { + it('should display correctly when an icon renderer is passed', async () => { const { container } = render( - }> - hello + }> + Hello World ) const avatarSvg = container.querySelector('svg') expect(avatarSvg).toBeInTheDocument() }) - it('should display correctly when an icon renderer is passed', async () => { + it('should render Lucide icon when passed as JSX element', async () => { const { container } = render( - }> - Hello World - + } + /> ) - const avatarSvg = container.querySelector('svg') - expect(avatarSvg).toBeInTheDocument() + + const svg = container.querySelector('svg') + expect(svg).toBeInTheDocument() + }) + + it('should render Lucide icon from render function', async () => { + const { container } = render( + } + /> + ) + + const svg = container.querySelector('svg') + expect(svg).toBeInTheDocument() }) }) @@ -126,7 +137,7 @@ describe('', () => { it('should display the image even if an icon is provided', async () => { const { container } = render( - } /> + ) const avatarImg = container.querySelector('img') expect(avatarImg).toHaveAttribute('src', src) @@ -195,7 +206,7 @@ describe('', () => { name="Jessica Jones" color="accent2" hasInverseColor - renderIcon={} + renderIcon={HeartInstUIIcon} /> ) const element = container.querySelector('div') diff --git a/packages/ui-avatar/src/Avatar/index.tsx b/packages/ui-avatar/src/Avatar/index.tsx index b13a8d39c0..aec016d032 100644 --- a/packages/ui-avatar/src/Avatar/index.tsx +++ b/packages/ui-avatar/src/Avatar/index.tsx @@ -22,14 +22,25 @@ * SOFTWARE. */ -import { useStyle, useTheme } from '@instructure/emotion' +import { useStyle } from '@instructure/emotion' import { useState, useEffect, forwardRef, SyntheticEvent } from 'react' -import { callRenderProp, passthroughProps } from '@instructure/ui-react-utils' -import type { AvatarProps } from './props' +import { passthroughProps } from '@instructure/ui-react-utils' +import { renderIconWithProps } from '@instructure/ui-icons-lucide' +import { AvatarProps, avatarSizeToIconSize } from './props' import generateStyle from './styles' +const ICON_COLOR_MAP = { + accent1: 'accentBlueColor', + accent2: 'accentGreenColor', + accent3: 'accentRedColor', + accent4: 'accentOrangeColor', + accent5: 'accentGreyColor', + accent6: 'accentAshColor', + ai: 'onColor' +} as const + /** --- category: components @@ -53,8 +64,6 @@ const Avatar = forwardRef( margin } = props const [loaded, setLoaded] = useState(false) - const theme = useTheme() - const iconTokens = (theme as any).newTheme.components.Icon const styles = useStyle({ generateStyle, @@ -68,8 +77,7 @@ const Avatar = forwardRef( src, showBorder, display, - margin, - iconTokens + margin }, componentId: 'Avatar', displayName: 'Avatar' @@ -136,9 +144,11 @@ const Avatar = forwardRef( } //icon in avatar - //TODO-REWORK make the icon inherit the size prop of the Avatar when the icons have it if (renderIcon) { - return callRenderProp(renderIcon) + const iconSize = avatarSizeToIconSize[size] + const iconColor = hasInverseColor ? 'onColor' : ICON_COLOR_MAP[color] + + return renderIconWithProps(renderIcon, iconSize, iconColor) } //initials in avatar diff --git a/packages/ui-avatar/src/Avatar/props.ts b/packages/ui-avatar/src/Avatar/props.ts index 4a3f3e8703..14b6d01a63 100644 --- a/packages/ui-avatar/src/Avatar/props.ts +++ b/packages/ui-avatar/src/Avatar/props.ts @@ -31,9 +31,19 @@ import type { } from '@instructure/emotion' import type { AsElementType, - OtherHTMLAttributes + OtherHTMLAttributes, + Renderable } from '@instructure/shared-types' -import { Renderable } from '@instructure/shared-types' + +const avatarSizeToIconSize = { + 'xx-small': 'xs', + 'x-small': 'xs', + small: 'sm', + medium: 'md', + large: 'lg', + 'x-large': 'xl', + 'xx-large': '2xl' +} as const type AvatarOwnProps = { /** @@ -48,14 +58,7 @@ type AvatarOwnProps = { * Accessible label */ alt?: string - size?: - | 'xx-small' - | 'x-small' - | 'small' - | 'medium' - | 'large' - | 'x-large' - | 'xx-large' + size?: keyof typeof avatarSizeToIconSize color?: | 'accent1' | 'accent2' @@ -96,6 +99,7 @@ type AvatarOwnProps = { elementRef?: (element: Element | null) => void /** * An icon, or function that returns an icon that gets displayed. If the `src` prop is provided, `src` will have priority. + * When using Lucide icons, Avatar will automatically pass the appropriate size and color props based on the Avatar's size and color. */ renderIcon?: Renderable } @@ -130,4 +134,4 @@ const allowedProps: AllowedPropKeys = [ ] export type { AvatarProps, AvatarStyle } -export { allowedProps } +export { allowedProps, avatarSizeToIconSize } diff --git a/packages/ui-avatar/src/Avatar/styles.ts b/packages/ui-avatar/src/Avatar/styles.ts index 4edc75dd65..fcfdb33560 100644 --- a/packages/ui-avatar/src/Avatar/styles.ts +++ b/packages/ui-avatar/src/Avatar/styles.ts @@ -36,7 +36,6 @@ type StyleParams = { showBorder: AvatarProps['showBorder'] display: AvatarProps['display'] margin: AvatarProps['margin'] - iconTokens: NewComponentTypes['Icon'] } /** * --- @@ -61,8 +60,7 @@ const generateStyle = ( shape, showBorder, display, - margin, - iconTokens + margin } = params const sizeStyles = { @@ -113,38 +111,31 @@ const generateStyle = ( const colorVariants = { accent1: { text: componentTheme.blueTextColor, - background: componentTheme.blueBackgroundColor, - icon: iconTokens.accentBlueColor + background: componentTheme.blueBackgroundColor }, accent2: { text: componentTheme.greenTextColor, - background: componentTheme.greenBackgroundColor, - icon: iconTokens.accentGreenColor + background: componentTheme.greenBackgroundColor }, accent3: { text: componentTheme.redTextColor, - background: componentTheme.redBackgroundColor, - icon: iconTokens.accentRedColor + background: componentTheme.redBackgroundColor }, accent4: { text: componentTheme.orangeTextColor, - background: componentTheme.orangeBackgroundColor, - icon: iconTokens.accentOrangeColor + background: componentTheme.orangeBackgroundColor }, accent5: { text: componentTheme.greyTextColor, - background: componentTheme.greyBackgroundColor, - icon: iconTokens.accentGreyColor + background: componentTheme.greyBackgroundColor }, accent6: { text: componentTheme.ashTextColor, - background: componentTheme.ashBackgroundColor, - icon: iconTokens.accentAshColor + background: componentTheme.ashBackgroundColor }, ai: { text: componentTheme.textOnColor, - background: `linear-gradient(135deg, ${componentTheme.aiTopGradientColor} 0%, ${componentTheme.aiBottomGradientColor} 100%)`, - icon: componentTheme.textOnColor + background: `linear-gradient(135deg, ${componentTheme.aiTopGradientColor} 0%, ${componentTheme.aiBottomGradientColor} 100%)` } } @@ -176,6 +167,7 @@ const generateStyle = ( display: display === 'inline' ? 'inline-flex' : 'flex', alignItems: 'center', justifyContent: 'center', + verticalAlign: 'middle', color: hasInverseColor ? componentTheme.textOnColor : colorVariants[color!].text, diff --git a/packages/ui-avatar/tsconfig.build.json b/packages/ui-avatar/tsconfig.build.json index 73379fbf32..67312882c9 100644 --- a/packages/ui-avatar/tsconfig.build.json +++ b/packages/ui-avatar/tsconfig.build.json @@ -32,7 +32,7 @@ "path": "../ui-themes/tsconfig.build.json" }, { - "path": "../ui-icons/tsconfig.build.json" + "path": "../ui-icons-lucide/tsconfig.build.json" } ] } diff --git a/packages/ui-icons-lucide/README.md b/packages/ui-icons-lucide/README.md index a4a698b447..0f0fea1134 100644 --- a/packages/ui-icons-lucide/README.md +++ b/packages/ui-icons-lucide/README.md @@ -32,8 +32,8 @@ const MyComponent = () => { return (
- - + +
) } diff --git a/packages/ui-icons-lucide/package.json b/packages/ui-icons-lucide/package.json index 3609bbd2a7..057d18ec10 100644 --- a/packages/ui-icons-lucide/package.json +++ b/packages/ui-icons-lucide/package.json @@ -28,7 +28,7 @@ "@instructure/ui-react-utils": "workspace:*", "@instructure/ui-themes": "workspace:*", "@instructure/ui-utils": "workspace:*", - "lucide-react": "^0.460.0" + "lucide-react": "^0.559.0" }, "devDependencies": { "@instructure/ui-babel-preset": "workspace:*", diff --git a/packages/ui-icons-lucide/scripts/generateIndex.ts b/packages/ui-icons-lucide/scripts/generateIndex.ts index 432e443505..a76f21245a 100644 --- a/packages/ui-icons-lucide/scripts/generateIndex.ts +++ b/packages/ui-icons-lucide/scripts/generateIndex.ts @@ -109,6 +109,8 @@ import { wrapLucideIcon } from './wrapLucideIcon' export type { LucideProps, LucideIcon } from 'lucide-react' export type { LucideIconWrapperProps, InstUIIconOwnProps } from './wrapLucideIcon' export { wrapLucideIcon } +export { IconPropsProvider, IconPropsContext, renderIconWithProps } from './IconPropsProvider' +export type { IconPropsContextValue } from './IconPropsProvider' ${iconExports} ` diff --git a/packages/ui-icons-lucide/src/IconPropsProvider/IconPropsContext.ts b/packages/ui-icons-lucide/src/IconPropsProvider/IconPropsContext.ts new file mode 100644 index 0000000000..3735d21415 --- /dev/null +++ b/packages/ui-icons-lucide/src/IconPropsProvider/IconPropsContext.ts @@ -0,0 +1,30 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import type { IconPropsContextValue } from './IconPropsProvider' + +const IconPropsContext = React.createContext({}) + +export { IconPropsContext } diff --git a/packages/ui-icons-lucide/src/IconPropsProvider/IconPropsProvider.tsx b/packages/ui-icons-lucide/src/IconPropsProvider/IconPropsProvider.tsx new file mode 100644 index 0000000000..65ebd83e1c --- /dev/null +++ b/packages/ui-icons-lucide/src/IconPropsProvider/IconPropsProvider.tsx @@ -0,0 +1,47 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { IconPropsContext } from './IconPropsContext' +import type { InstUIIconOwnProps } from '../wrapLucideIcon/props' + +type IconPropsContextValue = Pick + +type IconPropsProviderProps = React.PropsWithChildren + +const IconPropsProvider: React.FC = ({ + children, + size, + color +}) => { + const value = { size, color } + + return ( + + {children} + + ) +} + +export { IconPropsProvider } +export type { IconPropsContextValue } diff --git a/packages/ui-icons-lucide/src/IconPropsProvider/index.ts b/packages/ui-icons-lucide/src/IconPropsProvider/index.ts new file mode 100644 index 0000000000..7c506573dd --- /dev/null +++ b/packages/ui-icons-lucide/src/IconPropsProvider/index.ts @@ -0,0 +1,28 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +export { IconPropsProvider } from './IconPropsProvider' +export { IconPropsContext } from './IconPropsContext' +export { renderIconWithProps } from './renderIconWithProps' +export type { IconPropsContextValue } from './IconPropsProvider' diff --git a/packages/ui-icons-lucide/src/IconPropsProvider/renderIconWithProps.tsx b/packages/ui-icons-lucide/src/IconPropsProvider/renderIconWithProps.tsx new file mode 100644 index 0000000000..011e579d17 --- /dev/null +++ b/packages/ui-icons-lucide/src/IconPropsProvider/renderIconWithProps.tsx @@ -0,0 +1,62 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import type { Renderable } from '@instructure/shared-types' + +import { IconPropsProvider } from './IconPropsProvider' +import { InstUIIconOwnProps } from '../wrapLucideIcon/props' + +/** + * Renders an icon wrapped in IconPropsProvider to apply size and color via React context. + * Handles both component references and React elements. + * + * @param icon - The icon to render (component reference or React element) + * @param size - Semantic size token (e.g., 'xs', 'sm', 'md', 'lg', 'xl', '2xl'). + * @param color - Semantic color token (e.g., 'baseColor', 'errorColor', 'ai'). + * @returns Icon element wrapped in IconPropsProvider context + */ +function renderIconWithProps( + icon: Renderable, + size: InstUIIconOwnProps['size'], + color: InstUIIconOwnProps['color'] +): React.ReactElement { + let iconElement: React.ReactNode + + if (typeof icon === 'function') { + // It's a component (class or function) - use createElement + iconElement = React.createElement(icon as React.ComponentType) + } else { + // It's already a React element + iconElement = icon as React.ReactNode + } + + return ( + + {iconElement} + + ) +} + +export { renderIconWithProps } diff --git a/packages/ui-icons-lucide/src/__tests__/IconPropsProvider.test.tsx b/packages/ui-icons-lucide/src/__tests__/IconPropsProvider.test.tsx new file mode 100644 index 0000000000..25727a4740 --- /dev/null +++ b/packages/ui-icons-lucide/src/__tests__/IconPropsProvider.test.tsx @@ -0,0 +1,162 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { useContext } from 'react' +import { render, screen } from '@testing-library/react' +import '@testing-library/jest-dom' + +import { IconPropsProvider, IconPropsContext } from '../IconPropsProvider' + +// Test component that exposes context values +const TestComponentWithHook = () => { + const iconProps = useContext(IconPropsContext) + return ( +
+ + {iconProps?.size?.toString() || 'undefined'} + + {iconProps?.color || 'undefined'} +
+ ) +} + +// Mock icon component that uses context +const MockIconComponent = ({ testId = 'mock-icon' }: { testId?: string }) => { + const iconProps = useContext(IconPropsContext) + return ( +
+ Icon +
+ ) +} + +// Mock icon that accepts direct props and merges with context +const MockIconWithProps = ({ + size, + color, + testId = 'mock-icon-with-props' +}: { + size?: string + color?: string + testId?: string +}) => { + const contextProps = useContext(IconPropsContext) + const finalSize = size ?? contextProps?.size + const finalColor = color ?? contextProps?.color + + return ( +
+ Icon +
+ ) +} + +describe('IconPropsProvider', () => { + describe('useIconProps hook', () => { + it('should return context values when inside provider', () => { + render( + + + + ) + + expect(screen.getByTestId('size')).toHaveTextContent('lg') + expect(screen.getByTestId('color')).toHaveTextContent('baseColor') + }) + + it('should return empty object when outside provider', () => { + render() + + expect(screen.getByTestId('size')).toHaveTextContent('undefined') + expect(screen.getByTestId('color')).toHaveTextContent('undefined') + }) + + it('should return semantic size tokens', () => { + render( + + + + ) + + expect(screen.getByTestId('size')).toHaveTextContent('lg') + expect(screen.getByTestId('color')).toHaveTextContent('accentRedColor') + }) + }) + + describe('Icon components receive props from context', () => { + it('should pass context values to icon component', () => { + render( + + + + ) + + const icon = screen.getByTestId('mock-icon') + expect(icon).toHaveAttribute('data-size', 'md') + expect(icon).toHaveAttribute('data-color', 'baseColor') + }) + + it('should work without IconPropsProvider', () => { + render() + + const icon = screen.getByTestId('mock-icon') + expect(icon).toHaveAttribute('data-size', 'none') + expect(icon).toHaveAttribute('data-color', 'none') + }) + }) + + describe('Direct props override context props', () => { + it('should allow direct props to override context', () => { + render( + + + + ) + + const icon = screen.getByTestId('mock-icon-with-props') + expect(icon).toHaveAttribute('data-size', 'sm') + expect(icon).toHaveAttribute('data-color', 'accentRedColor') + }) + + it('should use context when no direct props provided', () => { + render( + + + + ) + + const icon = screen.getByTestId('mock-icon-with-props') + expect(icon).toHaveAttribute('data-size', 'lg') + expect(icon).toHaveAttribute('data-color', 'baseColor') + }) + }) +}) diff --git a/packages/ui-icons-lucide/src/index.ts b/packages/ui-icons-lucide/src/index.ts index d67428413d..2725ee5cb6 100644 --- a/packages/ui-icons-lucide/src/index.ts +++ b/packages/ui-icons-lucide/src/index.ts @@ -26,11 +26,13 @@ import * as Lucide from 'lucide-react' import { wrapLucideIcon } from './wrapLucideIcon' export type { LucideProps, LucideIcon } from 'lucide-react' -export type { - LucideIconWrapperProps, - InstUIIconOwnProps -} from './wrapLucideIcon' export { wrapLucideIcon } +export { + IconPropsProvider, + IconPropsContext, + renderIconWithProps +} from './IconPropsProvider' +export type { IconPropsContextValue } from './IconPropsProvider' export const AArrowDownInstUIIcon = wrapLucideIcon(Lucide.AArrowDown) export const AArrowUpInstUIIcon = wrapLucideIcon(Lucide.AArrowUp) @@ -292,16 +294,28 @@ export const BadgePlusInstUIIcon = wrapLucideIcon(Lucide.BadgePlus) export const BadgePoundSterlingInstUIIcon = wrapLucideIcon( Lucide.BadgePoundSterling ) +export const BadgeQuestionMarkInstUIIcon = wrapLucideIcon( + Lucide.BadgeQuestionMark +) export const BadgeRussianRubleInstUIIcon = wrapLucideIcon( Lucide.BadgeRussianRuble ) export const BadgeSwissFrancInstUIIcon = wrapLucideIcon(Lucide.BadgeSwissFranc) +export const BadgeTurkishLiraInstUIIcon = wrapLucideIcon( + Lucide.BadgeTurkishLira +) export const BadgeXInstUIIcon = wrapLucideIcon(Lucide.BadgeX) export const BaggageClaimInstUIIcon = wrapLucideIcon(Lucide.BaggageClaim) +export const BalloonInstUIIcon = wrapLucideIcon(Lucide.Balloon) export const BanInstUIIcon = wrapLucideIcon(Lucide.Ban) export const BananaInstUIIcon = wrapLucideIcon(Lucide.Banana) export const BandageInstUIIcon = wrapLucideIcon(Lucide.Bandage) export const BanknoteInstUIIcon = wrapLucideIcon(Lucide.Banknote) +export const BanknoteArrowDownInstUIIcon = wrapLucideIcon( + Lucide.BanknoteArrowDown +) +export const BanknoteArrowUpInstUIIcon = wrapLucideIcon(Lucide.BanknoteArrowUp) +export const BanknoteXInstUIIcon = wrapLucideIcon(Lucide.BanknoteX) export const BarChartInstUIIcon = wrapLucideIcon(Lucide.BarChart) export const BarChart2InstUIIcon = wrapLucideIcon(Lucide.BarChart2) export const BarChart3InstUIIcon = wrapLucideIcon(Lucide.BarChart3) @@ -314,6 +328,7 @@ export const BarChartHorizontalBigInstUIIcon = wrapLucideIcon( Lucide.BarChartHorizontalBig ) export const BarcodeInstUIIcon = wrapLucideIcon(Lucide.Barcode) +export const BarrelInstUIIcon = wrapLucideIcon(Lucide.Barrel) export const BaselineInstUIIcon = wrapLucideIcon(Lucide.Baseline) export const BathInstUIIcon = wrapLucideIcon(Lucide.Bath) export const BatteryInstUIIcon = wrapLucideIcon(Lucide.Battery) @@ -321,6 +336,7 @@ export const BatteryChargingInstUIIcon = wrapLucideIcon(Lucide.BatteryCharging) export const BatteryFullInstUIIcon = wrapLucideIcon(Lucide.BatteryFull) export const BatteryLowInstUIIcon = wrapLucideIcon(Lucide.BatteryLow) export const BatteryMediumInstUIIcon = wrapLucideIcon(Lucide.BatteryMedium) +export const BatteryPlusInstUIIcon = wrapLucideIcon(Lucide.BatteryPlus) export const BatteryWarningInstUIIcon = wrapLucideIcon(Lucide.BatteryWarning) export const BeakerInstUIIcon = wrapLucideIcon(Lucide.Beaker) export const BeanInstUIIcon = wrapLucideIcon(Lucide.Bean) @@ -362,6 +378,7 @@ export const BinaryInstUIIcon = wrapLucideIcon(Lucide.Binary) export const BinocularsInstUIIcon = wrapLucideIcon(Lucide.Binoculars) export const BiohazardInstUIIcon = wrapLucideIcon(Lucide.Biohazard) export const BirdInstUIIcon = wrapLucideIcon(Lucide.Bird) +export const BirdhouseInstUIIcon = wrapLucideIcon(Lucide.Birdhouse) export const BitcoinInstUIIcon = wrapLucideIcon(Lucide.Bitcoin) export const BlendInstUIIcon = wrapLucideIcon(Lucide.Blend) export const BlindsInstUIIcon = wrapLucideIcon(Lucide.Blinds) @@ -380,6 +397,7 @@ export const BombInstUIIcon = wrapLucideIcon(Lucide.Bomb) export const BoneInstUIIcon = wrapLucideIcon(Lucide.Bone) export const BookInstUIIcon = wrapLucideIcon(Lucide.Book) export const BookAInstUIIcon = wrapLucideIcon(Lucide.BookA) +export const BookAlertInstUIIcon = wrapLucideIcon(Lucide.BookAlert) export const BookAudioInstUIIcon = wrapLucideIcon(Lucide.BookAudio) export const BookCheckInstUIIcon = wrapLucideIcon(Lucide.BookCheck) export const BookCopyInstUIIcon = wrapLucideIcon(Lucide.BookCopy) @@ -396,6 +414,7 @@ export const BookOpenInstUIIcon = wrapLucideIcon(Lucide.BookOpen) export const BookOpenCheckInstUIIcon = wrapLucideIcon(Lucide.BookOpenCheck) export const BookOpenTextInstUIIcon = wrapLucideIcon(Lucide.BookOpenText) export const BookPlusInstUIIcon = wrapLucideIcon(Lucide.BookPlus) +export const BookSearchInstUIIcon = wrapLucideIcon(Lucide.BookSearch) export const BookTemplateInstUIIcon = wrapLucideIcon(Lucide.BookTemplate) export const BookTextInstUIIcon = wrapLucideIcon(Lucide.BookText) export const BookTypeInstUIIcon = wrapLucideIcon(Lucide.BookType) @@ -414,6 +433,8 @@ export const BotMessageSquareInstUIIcon = wrapLucideIcon( Lucide.BotMessageSquare ) export const BotOffInstUIIcon = wrapLucideIcon(Lucide.BotOff) +export const BottleWineInstUIIcon = wrapLucideIcon(Lucide.BottleWine) +export const BowArrowInstUIIcon = wrapLucideIcon(Lucide.BowArrow) export const BoxInstUIIcon = wrapLucideIcon(Lucide.Box) export const BoxSelectInstUIIcon = wrapLucideIcon(Lucide.BoxSelect) export const BoxesInstUIIcon = wrapLucideIcon(Lucide.Boxes) @@ -423,6 +444,8 @@ export const BrainInstUIIcon = wrapLucideIcon(Lucide.Brain) export const BrainCircuitInstUIIcon = wrapLucideIcon(Lucide.BrainCircuit) export const BrainCogInstUIIcon = wrapLucideIcon(Lucide.BrainCog) export const BrickWallInstUIIcon = wrapLucideIcon(Lucide.BrickWall) +export const BrickWallFireInstUIIcon = wrapLucideIcon(Lucide.BrickWallFire) +export const BrickWallShieldInstUIIcon = wrapLucideIcon(Lucide.BrickWallShield) export const BriefcaseInstUIIcon = wrapLucideIcon(Lucide.Briefcase) export const BriefcaseBusinessInstUIIcon = wrapLucideIcon( Lucide.BriefcaseBusiness @@ -435,6 +458,8 @@ export const BriefcaseMedicalInstUIIcon = wrapLucideIcon( ) export const BringToFrontInstUIIcon = wrapLucideIcon(Lucide.BringToFront) export const BrushInstUIIcon = wrapLucideIcon(Lucide.Brush) +export const BrushCleaningInstUIIcon = wrapLucideIcon(Lucide.BrushCleaning) +export const BubblesInstUIIcon = wrapLucideIcon(Lucide.Bubbles) export const BugInstUIIcon = wrapLucideIcon(Lucide.Bug) export const BugOffInstUIIcon = wrapLucideIcon(Lucide.BugOff) export const BugPlayInstUIIcon = wrapLucideIcon(Lucide.BugPlay) @@ -467,8 +492,10 @@ export const CalendarPlusInstUIIcon = wrapLucideIcon(Lucide.CalendarPlus) export const CalendarPlus2InstUIIcon = wrapLucideIcon(Lucide.CalendarPlus2) export const CalendarRangeInstUIIcon = wrapLucideIcon(Lucide.CalendarRange) export const CalendarSearchInstUIIcon = wrapLucideIcon(Lucide.CalendarSearch) +export const CalendarSyncInstUIIcon = wrapLucideIcon(Lucide.CalendarSync) export const CalendarXInstUIIcon = wrapLucideIcon(Lucide.CalendarX) export const CalendarX2InstUIIcon = wrapLucideIcon(Lucide.CalendarX2) +export const CalendarsInstUIIcon = wrapLucideIcon(Lucide.Calendars) export const CameraInstUIIcon = wrapLucideIcon(Lucide.Camera) export const CameraOffInstUIIcon = wrapLucideIcon(Lucide.CameraOff) export const CandlestickChartInstUIIcon = wrapLucideIcon( @@ -484,6 +511,7 @@ export const CarInstUIIcon = wrapLucideIcon(Lucide.Car) export const CarFrontInstUIIcon = wrapLucideIcon(Lucide.CarFront) export const CarTaxiFrontInstUIIcon = wrapLucideIcon(Lucide.CarTaxiFront) export const CaravanInstUIIcon = wrapLucideIcon(Lucide.Caravan) +export const CardSimInstUIIcon = wrapLucideIcon(Lucide.CardSim) export const CarrotInstUIIcon = wrapLucideIcon(Lucide.Carrot) export const CaseLowerInstUIIcon = wrapLucideIcon(Lucide.CaseLower) export const CaseSensitiveInstUIIcon = wrapLucideIcon(Lucide.CaseSensitive) @@ -542,10 +570,17 @@ export const CheckInstUIIcon = wrapLucideIcon(Lucide.Check) export const CheckCheckInstUIIcon = wrapLucideIcon(Lucide.CheckCheck) export const CheckCircleInstUIIcon = wrapLucideIcon(Lucide.CheckCircle) export const CheckCircle2InstUIIcon = wrapLucideIcon(Lucide.CheckCircle2) +export const CheckLineInstUIIcon = wrapLucideIcon(Lucide.CheckLine) export const CheckSquareInstUIIcon = wrapLucideIcon(Lucide.CheckSquare) export const CheckSquare2InstUIIcon = wrapLucideIcon(Lucide.CheckSquare2) export const ChefHatInstUIIcon = wrapLucideIcon(Lucide.ChefHat) export const CherryInstUIIcon = wrapLucideIcon(Lucide.Cherry) +export const ChessBishopInstUIIcon = wrapLucideIcon(Lucide.ChessBishop) +export const ChessKingInstUIIcon = wrapLucideIcon(Lucide.ChessKing) +export const ChessKnightInstUIIcon = wrapLucideIcon(Lucide.ChessKnight) +export const ChessPawnInstUIIcon = wrapLucideIcon(Lucide.ChessPawn) +export const ChessQueenInstUIIcon = wrapLucideIcon(Lucide.ChessQueen) +export const ChessRookInstUIIcon = wrapLucideIcon(Lucide.ChessRook) export const ChevronDownInstUIIcon = wrapLucideIcon(Lucide.ChevronDown) export const ChevronDownCircleInstUIIcon = wrapLucideIcon( Lucide.ChevronDownCircle @@ -588,6 +623,7 @@ export const ChevronsRightLeftInstUIIcon = wrapLucideIcon( export const ChevronsUpInstUIIcon = wrapLucideIcon(Lucide.ChevronsUp) export const ChevronsUpDownInstUIIcon = wrapLucideIcon(Lucide.ChevronsUpDown) export const ChromeInstUIIcon = wrapLucideIcon(Lucide.Chrome) +export const ChromiumInstUIIcon = wrapLucideIcon(Lucide.Chromium) export const ChurchInstUIIcon = wrapLucideIcon(Lucide.Church) export const CigaretteInstUIIcon = wrapLucideIcon(Lucide.Cigarette) export const CigaretteOffInstUIIcon = wrapLucideIcon(Lucide.CigaretteOff) @@ -648,12 +684,21 @@ export const CircleParkingOffInstUIIcon = wrapLucideIcon( ) export const CirclePauseInstUIIcon = wrapLucideIcon(Lucide.CirclePause) export const CirclePercentInstUIIcon = wrapLucideIcon(Lucide.CirclePercent) +export const CirclePileInstUIIcon = wrapLucideIcon(Lucide.CirclePile) export const CirclePlayInstUIIcon = wrapLucideIcon(Lucide.CirclePlay) export const CirclePlusInstUIIcon = wrapLucideIcon(Lucide.CirclePlus) +export const CirclePoundSterlingInstUIIcon = wrapLucideIcon( + Lucide.CirclePoundSterling +) export const CirclePowerInstUIIcon = wrapLucideIcon(Lucide.CirclePower) +export const CircleQuestionMarkInstUIIcon = wrapLucideIcon( + Lucide.CircleQuestionMark +) export const CircleSlashInstUIIcon = wrapLucideIcon(Lucide.CircleSlash) export const CircleSlash2InstUIIcon = wrapLucideIcon(Lucide.CircleSlash2) export const CircleSlashedInstUIIcon = wrapLucideIcon(Lucide.CircleSlashed) +export const CircleSmallInstUIIcon = wrapLucideIcon(Lucide.CircleSmall) +export const CircleStarInstUIIcon = wrapLucideIcon(Lucide.CircleStar) export const CircleStopInstUIIcon = wrapLucideIcon(Lucide.CircleStop) export const CircleUserInstUIIcon = wrapLucideIcon(Lucide.CircleUser) export const CircleUserRoundInstUIIcon = wrapLucideIcon(Lucide.CircleUserRound) @@ -663,6 +708,7 @@ export const CitrusInstUIIcon = wrapLucideIcon(Lucide.Citrus) export const ClapperboardInstUIIcon = wrapLucideIcon(Lucide.Clapperboard) export const ClipboardInstUIIcon = wrapLucideIcon(Lucide.Clipboard) export const ClipboardCheckInstUIIcon = wrapLucideIcon(Lucide.ClipboardCheck) +export const ClipboardClockInstUIIcon = wrapLucideIcon(Lucide.ClipboardClock) export const ClipboardCopyInstUIIcon = wrapLucideIcon(Lucide.ClipboardCopy) export const ClipboardEditInstUIIcon = wrapLucideIcon(Lucide.ClipboardEdit) export const ClipboardListInstUIIcon = wrapLucideIcon(Lucide.ClipboardList) @@ -694,8 +740,14 @@ export const Clock9InstUIIcon = wrapLucideIcon(Lucide.Clock9) export const ClockAlertInstUIIcon = wrapLucideIcon(Lucide.ClockAlert) export const ClockArrowDownInstUIIcon = wrapLucideIcon(Lucide.ClockArrowDown) export const ClockArrowUpInstUIIcon = wrapLucideIcon(Lucide.ClockArrowUp) +export const ClockCheckInstUIIcon = wrapLucideIcon(Lucide.ClockCheck) +export const ClockFadingInstUIIcon = wrapLucideIcon(Lucide.ClockFading) +export const ClockPlusInstUIIcon = wrapLucideIcon(Lucide.ClockPlus) +export const ClosedCaptionInstUIIcon = wrapLucideIcon(Lucide.ClosedCaption) export const CloudInstUIIcon = wrapLucideIcon(Lucide.Cloud) export const CloudAlertInstUIIcon = wrapLucideIcon(Lucide.CloudAlert) +export const CloudBackupInstUIIcon = wrapLucideIcon(Lucide.CloudBackup) +export const CloudCheckInstUIIcon = wrapLucideIcon(Lucide.CloudCheck) export const CloudCogInstUIIcon = wrapLucideIcon(Lucide.CloudCog) export const CloudDownloadInstUIIcon = wrapLucideIcon(Lucide.CloudDownload) export const CloudDrizzleInstUIIcon = wrapLucideIcon(Lucide.CloudDrizzle) @@ -710,6 +762,7 @@ export const CloudRainWindInstUIIcon = wrapLucideIcon(Lucide.CloudRainWind) export const CloudSnowInstUIIcon = wrapLucideIcon(Lucide.CloudSnow) export const CloudSunInstUIIcon = wrapLucideIcon(Lucide.CloudSun) export const CloudSunRainInstUIIcon = wrapLucideIcon(Lucide.CloudSunRain) +export const CloudSyncInstUIIcon = wrapLucideIcon(Lucide.CloudSync) export const CloudUploadInstUIIcon = wrapLucideIcon(Lucide.CloudUpload) export const CloudyInstUIIcon = wrapLucideIcon(Lucide.Cloudy) export const CloverInstUIIcon = wrapLucideIcon(Lucide.Clover) @@ -726,7 +779,9 @@ export const CoinsInstUIIcon = wrapLucideIcon(Lucide.Coins) export const ColumnsInstUIIcon = wrapLucideIcon(Lucide.Columns) export const Columns2InstUIIcon = wrapLucideIcon(Lucide.Columns2) export const Columns3InstUIIcon = wrapLucideIcon(Lucide.Columns3) +export const Columns3CogInstUIIcon = wrapLucideIcon(Lucide.Columns3Cog) export const Columns4InstUIIcon = wrapLucideIcon(Lucide.Columns4) +export const ColumnsSettingsInstUIIcon = wrapLucideIcon(Lucide.ColumnsSettings) export const CombineInstUIIcon = wrapLucideIcon(Lucide.Combine) export const CommandInstUIIcon = wrapLucideIcon(Lucide.Command) export const CompassInstUIIcon = wrapLucideIcon(Lucide.Compass) @@ -775,6 +830,12 @@ export const DamInstUIIcon = wrapLucideIcon(Lucide.Dam) export const DatabaseInstUIIcon = wrapLucideIcon(Lucide.Database) export const DatabaseBackupInstUIIcon = wrapLucideIcon(Lucide.DatabaseBackup) export const DatabaseZapInstUIIcon = wrapLucideIcon(Lucide.DatabaseZap) +export const DecimalsArrowLeftInstUIIcon = wrapLucideIcon( + Lucide.DecimalsArrowLeft +) +export const DecimalsArrowRightInstUIIcon = wrapLucideIcon( + Lucide.DecimalsArrowRight +) export const DeleteInstUIIcon = wrapLucideIcon(Lucide.Delete) export const DessertInstUIIcon = wrapLucideIcon(Lucide.Dessert) export const DiameterInstUIIcon = wrapLucideIcon(Lucide.Diameter) @@ -804,6 +865,9 @@ export const DogInstUIIcon = wrapLucideIcon(Lucide.Dog) export const DollarSignInstUIIcon = wrapLucideIcon(Lucide.DollarSign) export const DonutInstUIIcon = wrapLucideIcon(Lucide.Donut) export const DoorClosedInstUIIcon = wrapLucideIcon(Lucide.DoorClosed) +export const DoorClosedLockedInstUIIcon = wrapLucideIcon( + Lucide.DoorClosedLocked +) export const DoorOpenInstUIIcon = wrapLucideIcon(Lucide.DoorOpen) export const DotInstUIIcon = wrapLucideIcon(Lucide.Dot) export const DotSquareInstUIIcon = wrapLucideIcon(Lucide.DotSquare) @@ -813,7 +877,9 @@ export const DraftingCompassInstUIIcon = wrapLucideIcon(Lucide.DraftingCompass) export const DramaInstUIIcon = wrapLucideIcon(Lucide.Drama) export const DribbbleInstUIIcon = wrapLucideIcon(Lucide.Dribbble) export const DrillInstUIIcon = wrapLucideIcon(Lucide.Drill) +export const DroneInstUIIcon = wrapLucideIcon(Lucide.Drone) export const DropletInstUIIcon = wrapLucideIcon(Lucide.Droplet) +export const DropletOffInstUIIcon = wrapLucideIcon(Lucide.DropletOff) export const DropletsInstUIIcon = wrapLucideIcon(Lucide.Droplets) export const DrumInstUIIcon = wrapLucideIcon(Lucide.Drum) export const DrumstickInstUIIcon = wrapLucideIcon(Lucide.Drumstick) @@ -842,6 +908,7 @@ export const EqualSquareInstUIIcon = wrapLucideIcon(Lucide.EqualSquare) export const EraserInstUIIcon = wrapLucideIcon(Lucide.Eraser) export const EthernetPortInstUIIcon = wrapLucideIcon(Lucide.EthernetPort) export const EuroInstUIIcon = wrapLucideIcon(Lucide.Euro) +export const EvChargerInstUIIcon = wrapLucideIcon(Lucide.EvCharger) export const ExpandInstUIIcon = wrapLucideIcon(Lucide.Expand) export const ExternalLinkInstUIIcon = wrapLucideIcon(Lucide.ExternalLink) export const EyeInstUIIcon = wrapLucideIcon(Lucide.Eye) @@ -866,6 +933,10 @@ export const FileBadge2InstUIIcon = wrapLucideIcon(Lucide.FileBadge2) export const FileBarChartInstUIIcon = wrapLucideIcon(Lucide.FileBarChart) export const FileBarChart2InstUIIcon = wrapLucideIcon(Lucide.FileBarChart2) export const FileBoxInstUIIcon = wrapLucideIcon(Lucide.FileBox) +export const FileBracesInstUIIcon = wrapLucideIcon(Lucide.FileBraces) +export const FileBracesCornerInstUIIcon = wrapLucideIcon( + Lucide.FileBracesCorner +) export const FileChartColumnInstUIIcon = wrapLucideIcon(Lucide.FileChartColumn) export const FileChartColumnIncreasingInstUIIcon = wrapLucideIcon( Lucide.FileChartColumnIncreasing @@ -874,15 +945,21 @@ export const FileChartLineInstUIIcon = wrapLucideIcon(Lucide.FileChartLine) export const FileChartPieInstUIIcon = wrapLucideIcon(Lucide.FileChartPie) export const FileCheckInstUIIcon = wrapLucideIcon(Lucide.FileCheck) export const FileCheck2InstUIIcon = wrapLucideIcon(Lucide.FileCheck2) +export const FileCheckCornerInstUIIcon = wrapLucideIcon(Lucide.FileCheckCorner) export const FileClockInstUIIcon = wrapLucideIcon(Lucide.FileClock) export const FileCodeInstUIIcon = wrapLucideIcon(Lucide.FileCode) export const FileCode2InstUIIcon = wrapLucideIcon(Lucide.FileCode2) +export const FileCodeCornerInstUIIcon = wrapLucideIcon(Lucide.FileCodeCorner) export const FileCogInstUIIcon = wrapLucideIcon(Lucide.FileCog) export const FileCog2InstUIIcon = wrapLucideIcon(Lucide.FileCog2) export const FileDiffInstUIIcon = wrapLucideIcon(Lucide.FileDiff) export const FileDigitInstUIIcon = wrapLucideIcon(Lucide.FileDigit) export const FileDownInstUIIcon = wrapLucideIcon(Lucide.FileDown) export const FileEditInstUIIcon = wrapLucideIcon(Lucide.FileEdit) +export const FileExclamationPointInstUIIcon = wrapLucideIcon( + Lucide.FileExclamationPoint +) +export const FileHeadphoneInstUIIcon = wrapLucideIcon(Lucide.FileHeadphone) export const FileHeartInstUIIcon = wrapLucideIcon(Lucide.FileHeart) export const FileImageInstUIIcon = wrapLucideIcon(Lucide.FileImage) export const FileInputInstUIIcon = wrapLucideIcon(Lucide.FileInput) @@ -895,17 +972,27 @@ export const FileLockInstUIIcon = wrapLucideIcon(Lucide.FileLock) export const FileLock2InstUIIcon = wrapLucideIcon(Lucide.FileLock2) export const FileMinusInstUIIcon = wrapLucideIcon(Lucide.FileMinus) export const FileMinus2InstUIIcon = wrapLucideIcon(Lucide.FileMinus2) +export const FileMinusCornerInstUIIcon = wrapLucideIcon(Lucide.FileMinusCorner) export const FileMusicInstUIIcon = wrapLucideIcon(Lucide.FileMusic) export const FileOutputInstUIIcon = wrapLucideIcon(Lucide.FileOutput) export const FilePenInstUIIcon = wrapLucideIcon(Lucide.FilePen) export const FilePenLineInstUIIcon = wrapLucideIcon(Lucide.FilePenLine) export const FilePieChartInstUIIcon = wrapLucideIcon(Lucide.FilePieChart) +export const FilePlayInstUIIcon = wrapLucideIcon(Lucide.FilePlay) export const FilePlusInstUIIcon = wrapLucideIcon(Lucide.FilePlus) export const FilePlus2InstUIIcon = wrapLucideIcon(Lucide.FilePlus2) +export const FilePlusCornerInstUIIcon = wrapLucideIcon(Lucide.FilePlusCorner) export const FileQuestionInstUIIcon = wrapLucideIcon(Lucide.FileQuestion) +export const FileQuestionMarkInstUIIcon = wrapLucideIcon( + Lucide.FileQuestionMark +) export const FileScanInstUIIcon = wrapLucideIcon(Lucide.FileScan) export const FileSearchInstUIIcon = wrapLucideIcon(Lucide.FileSearch) export const FileSearch2InstUIIcon = wrapLucideIcon(Lucide.FileSearch2) +export const FileSearchCornerInstUIIcon = wrapLucideIcon( + Lucide.FileSearchCorner +) +export const FileSignalInstUIIcon = wrapLucideIcon(Lucide.FileSignal) export const FileSignatureInstUIIcon = wrapLucideIcon(Lucide.FileSignature) export const FileSlidersInstUIIcon = wrapLucideIcon(Lucide.FileSliders) export const FileSpreadsheetInstUIIcon = wrapLucideIcon(Lucide.FileSpreadsheet) @@ -915,26 +1002,33 @@ export const FileTerminalInstUIIcon = wrapLucideIcon(Lucide.FileTerminal) export const FileTextInstUIIcon = wrapLucideIcon(Lucide.FileText) export const FileTypeInstUIIcon = wrapLucideIcon(Lucide.FileType) export const FileType2InstUIIcon = wrapLucideIcon(Lucide.FileType2) +export const FileTypeCornerInstUIIcon = wrapLucideIcon(Lucide.FileTypeCorner) export const FileUpInstUIIcon = wrapLucideIcon(Lucide.FileUp) export const FileUserInstUIIcon = wrapLucideIcon(Lucide.FileUser) export const FileVideoInstUIIcon = wrapLucideIcon(Lucide.FileVideo) export const FileVideo2InstUIIcon = wrapLucideIcon(Lucide.FileVideo2) +export const FileVideoCameraInstUIIcon = wrapLucideIcon(Lucide.FileVideoCamera) export const FileVolumeInstUIIcon = wrapLucideIcon(Lucide.FileVolume) export const FileVolume2InstUIIcon = wrapLucideIcon(Lucide.FileVolume2) export const FileWarningInstUIIcon = wrapLucideIcon(Lucide.FileWarning) export const FileXInstUIIcon = wrapLucideIcon(Lucide.FileX) export const FileX2InstUIIcon = wrapLucideIcon(Lucide.FileX2) +export const FileXCornerInstUIIcon = wrapLucideIcon(Lucide.FileXCorner) export const FilesInstUIIcon = wrapLucideIcon(Lucide.Files) export const FilmInstUIIcon = wrapLucideIcon(Lucide.Film) export const FilterInstUIIcon = wrapLucideIcon(Lucide.Filter) export const FilterXInstUIIcon = wrapLucideIcon(Lucide.FilterX) export const FingerprintInstUIIcon = wrapLucideIcon(Lucide.Fingerprint) +export const FingerprintPatternInstUIIcon = wrapLucideIcon( + Lucide.FingerprintPattern +) export const FireExtinguisherInstUIIcon = wrapLucideIcon( Lucide.FireExtinguisher ) export const FishInstUIIcon = wrapLucideIcon(Lucide.Fish) export const FishOffInstUIIcon = wrapLucideIcon(Lucide.FishOff) export const FishSymbolInstUIIcon = wrapLucideIcon(Lucide.FishSymbol) +export const FishingHookInstUIIcon = wrapLucideIcon(Lucide.FishingHook) export const FlagInstUIIcon = wrapLucideIcon(Lucide.Flag) export const FlagOffInstUIIcon = wrapLucideIcon(Lucide.FlagOff) export const FlagTriangleLeftInstUIIcon = wrapLucideIcon( @@ -998,6 +1092,7 @@ export const ForkKnifeCrossedInstUIIcon = wrapLucideIcon( Lucide.ForkKnifeCrossed ) export const ForkliftInstUIIcon = wrapLucideIcon(Lucide.Forklift) +export const FormInstUIIcon = wrapLucideIcon(Lucide.Form) export const FormInputInstUIIcon = wrapLucideIcon(Lucide.FormInput) export const ForwardInstUIIcon = wrapLucideIcon(Lucide.Forward) export const FrameInstUIIcon = wrapLucideIcon(Lucide.Frame) @@ -1006,6 +1101,9 @@ export const FrownInstUIIcon = wrapLucideIcon(Lucide.Frown) export const FuelInstUIIcon = wrapLucideIcon(Lucide.Fuel) export const FullscreenInstUIIcon = wrapLucideIcon(Lucide.Fullscreen) export const FunctionSquareInstUIIcon = wrapLucideIcon(Lucide.FunctionSquare) +export const FunnelInstUIIcon = wrapLucideIcon(Lucide.Funnel) +export const FunnelPlusInstUIIcon = wrapLucideIcon(Lucide.FunnelPlus) +export const FunnelXInstUIIcon = wrapLucideIcon(Lucide.FunnelX) export const GalleryHorizontalInstUIIcon = wrapLucideIcon( Lucide.GalleryHorizontal ) @@ -1021,6 +1119,9 @@ export const GalleryVerticalEndInstUIIcon = wrapLucideIcon( ) export const GamepadInstUIIcon = wrapLucideIcon(Lucide.Gamepad) export const Gamepad2InstUIIcon = wrapLucideIcon(Lucide.Gamepad2) +export const GamepadDirectionalInstUIIcon = wrapLucideIcon( + Lucide.GamepadDirectional +) export const GanttChartInstUIIcon = wrapLucideIcon(Lucide.GanttChart) export const GanttChartSquareInstUIIcon = wrapLucideIcon( Lucide.GanttChartSquare @@ -1029,9 +1130,11 @@ export const GaugeInstUIIcon = wrapLucideIcon(Lucide.Gauge) export const GaugeCircleInstUIIcon = wrapLucideIcon(Lucide.GaugeCircle) export const GavelInstUIIcon = wrapLucideIcon(Lucide.Gavel) export const GemInstUIIcon = wrapLucideIcon(Lucide.Gem) +export const GeorgianLariInstUIIcon = wrapLucideIcon(Lucide.GeorgianLari) export const GhostInstUIIcon = wrapLucideIcon(Lucide.Ghost) export const GiftInstUIIcon = wrapLucideIcon(Lucide.Gift) export const GitBranchInstUIIcon = wrapLucideIcon(Lucide.GitBranch) +export const GitBranchMinusInstUIIcon = wrapLucideIcon(Lucide.GitBranchMinus) export const GitBranchPlusInstUIIcon = wrapLucideIcon(Lucide.GitBranchPlus) export const GitCommitInstUIIcon = wrapLucideIcon(Lucide.GitCommit) export const GitCommitHorizontalInstUIIcon = wrapLucideIcon( @@ -1071,17 +1174,21 @@ export const GlobeInstUIIcon = wrapLucideIcon(Lucide.Globe) export const Globe2InstUIIcon = wrapLucideIcon(Lucide.Globe2) export const GlobeLockInstUIIcon = wrapLucideIcon(Lucide.GlobeLock) export const GoalInstUIIcon = wrapLucideIcon(Lucide.Goal) +export const GpuInstUIIcon = wrapLucideIcon(Lucide.Gpu) export const GrabInstUIIcon = wrapLucideIcon(Lucide.Grab) export const GraduationCapInstUIIcon = wrapLucideIcon(Lucide.GraduationCap) export const GrapeInstUIIcon = wrapLucideIcon(Lucide.Grape) export const GridInstUIIcon = wrapLucideIcon(Lucide.Grid) export const Grid2X2InstUIIcon = wrapLucideIcon(Lucide.Grid2X2) +export const Grid2X2CheckInstUIIcon = wrapLucideIcon(Lucide.Grid2X2Check) export const Grid2X2PlusInstUIIcon = wrapLucideIcon(Lucide.Grid2X2Plus) +export const Grid2X2XInstUIIcon = wrapLucideIcon(Lucide.Grid2X2X) export const Grid2x2InstUIIcon = wrapLucideIcon(Lucide.Grid2x2) export const Grid2x2CheckInstUIIcon = wrapLucideIcon(Lucide.Grid2x2Check) export const Grid2x2PlusInstUIIcon = wrapLucideIcon(Lucide.Grid2x2Plus) export const Grid2x2XInstUIIcon = wrapLucideIcon(Lucide.Grid2x2X) export const Grid3X3InstUIIcon = wrapLucideIcon(Lucide.Grid3X3) +export const Grid3x2InstUIIcon = wrapLucideIcon(Lucide.Grid3x2) export const Grid3x3InstUIIcon = wrapLucideIcon(Lucide.Grid3x3) export const GripInstUIIcon = wrapLucideIcon(Lucide.Grip) export const GripHorizontalInstUIIcon = wrapLucideIcon(Lucide.GripHorizontal) @@ -1089,13 +1196,17 @@ export const GripVerticalInstUIIcon = wrapLucideIcon(Lucide.GripVertical) export const GroupInstUIIcon = wrapLucideIcon(Lucide.Group) export const GuitarInstUIIcon = wrapLucideIcon(Lucide.Guitar) export const HamInstUIIcon = wrapLucideIcon(Lucide.Ham) +export const HamburgerInstUIIcon = wrapLucideIcon(Lucide.Hamburger) export const HammerInstUIIcon = wrapLucideIcon(Lucide.Hammer) export const HandInstUIIcon = wrapLucideIcon(Lucide.Hand) export const HandCoinsInstUIIcon = wrapLucideIcon(Lucide.HandCoins) +export const HandFistInstUIIcon = wrapLucideIcon(Lucide.HandFist) +export const HandGrabInstUIIcon = wrapLucideIcon(Lucide.HandGrab) export const HandHeartInstUIIcon = wrapLucideIcon(Lucide.HandHeart) export const HandHelpingInstUIIcon = wrapLucideIcon(Lucide.HandHelping) export const HandMetalInstUIIcon = wrapLucideIcon(Lucide.HandMetal) export const HandPlatterInstUIIcon = wrapLucideIcon(Lucide.HandPlatter) +export const HandbagInstUIIcon = wrapLucideIcon(Lucide.Handbag) export const HandshakeInstUIIcon = wrapLucideIcon(Lucide.Handshake) export const HardDriveInstUIIcon = wrapLucideIcon(Lucide.HardDrive) export const HardDriveDownloadInstUIIcon = wrapLucideIcon( @@ -1104,7 +1215,9 @@ export const HardDriveDownloadInstUIIcon = wrapLucideIcon( export const HardDriveUploadInstUIIcon = wrapLucideIcon(Lucide.HardDriveUpload) export const HardHatInstUIIcon = wrapLucideIcon(Lucide.HardHat) export const HashInstUIIcon = wrapLucideIcon(Lucide.Hash) +export const HatGlassesInstUIIcon = wrapLucideIcon(Lucide.HatGlasses) export const HazeInstUIIcon = wrapLucideIcon(Lucide.Haze) +export const HdInstUIIcon = wrapLucideIcon(Lucide.Hd) export const HdmiPortInstUIIcon = wrapLucideIcon(Lucide.HdmiPort) export const HeadingInstUIIcon = wrapLucideIcon(Lucide.Heading) export const Heading1InstUIIcon = wrapLucideIcon(Lucide.Heading1) @@ -1119,9 +1232,12 @@ export const HeadsetInstUIIcon = wrapLucideIcon(Lucide.Headset) export const HeartInstUIIcon = wrapLucideIcon(Lucide.Heart) export const HeartCrackInstUIIcon = wrapLucideIcon(Lucide.HeartCrack) export const HeartHandshakeInstUIIcon = wrapLucideIcon(Lucide.HeartHandshake) +export const HeartMinusInstUIIcon = wrapLucideIcon(Lucide.HeartMinus) export const HeartOffInstUIIcon = wrapLucideIcon(Lucide.HeartOff) +export const HeartPlusInstUIIcon = wrapLucideIcon(Lucide.HeartPlus) export const HeartPulseInstUIIcon = wrapLucideIcon(Lucide.HeartPulse) export const HeaterInstUIIcon = wrapLucideIcon(Lucide.Heater) +export const HelicopterInstUIIcon = wrapLucideIcon(Lucide.Helicopter) export const HelpCircleInstUIIcon = wrapLucideIcon(Lucide.HelpCircle) export const HelpingHandInstUIIcon = wrapLucideIcon(Lucide.HelpingHand) export const HexagonInstUIIcon = wrapLucideIcon(Lucide.Hexagon) @@ -1134,13 +1250,16 @@ export const HospitalInstUIIcon = wrapLucideIcon(Lucide.Hospital) export const HotelInstUIIcon = wrapLucideIcon(Lucide.Hotel) export const HourglassInstUIIcon = wrapLucideIcon(Lucide.Hourglass) export const HouseInstUIIcon = wrapLucideIcon(Lucide.House) +export const HouseHeartInstUIIcon = wrapLucideIcon(Lucide.HouseHeart) export const HousePlugInstUIIcon = wrapLucideIcon(Lucide.HousePlug) export const HousePlusInstUIIcon = wrapLucideIcon(Lucide.HousePlus) +export const HouseWifiInstUIIcon = wrapLucideIcon(Lucide.HouseWifi) export const IceCreamInstUIIcon = wrapLucideIcon(Lucide.IceCream) export const IceCream2InstUIIcon = wrapLucideIcon(Lucide.IceCream2) export const IceCreamBowlInstUIIcon = wrapLucideIcon(Lucide.IceCreamBowl) export const IceCreamConeInstUIIcon = wrapLucideIcon(Lucide.IceCreamCone) export const IdCardInstUIIcon = wrapLucideIcon(Lucide.IdCard) +export const IdCardLanyardInstUIIcon = wrapLucideIcon(Lucide.IdCardLanyard) export const ImageInstUIIcon = wrapLucideIcon(Lucide.Image) export const ImageDownInstUIIcon = wrapLucideIcon(Lucide.ImageDown) export const ImageMinusInstUIIcon = wrapLucideIcon(Lucide.ImageMinus) @@ -1148,6 +1267,7 @@ export const ImageOffInstUIIcon = wrapLucideIcon(Lucide.ImageOff) export const ImagePlayInstUIIcon = wrapLucideIcon(Lucide.ImagePlay) export const ImagePlusInstUIIcon = wrapLucideIcon(Lucide.ImagePlus) export const ImageUpInstUIIcon = wrapLucideIcon(Lucide.ImageUp) +export const ImageUpscaleInstUIIcon = wrapLucideIcon(Lucide.ImageUpscale) export const ImagesInstUIIcon = wrapLucideIcon(Lucide.Images) export const ImportInstUIIcon = wrapLucideIcon(Lucide.Import) export const InboxInstUIIcon = wrapLucideIcon(Lucide.Inbox) @@ -1170,6 +1290,7 @@ export const KanbanSquareInstUIIcon = wrapLucideIcon(Lucide.KanbanSquare) export const KanbanSquareDashedInstUIIcon = wrapLucideIcon( Lucide.KanbanSquareDashed ) +export const KayakInstUIIcon = wrapLucideIcon(Lucide.Kayak) export const KeyInstUIIcon = wrapLucideIcon(Lucide.Key) export const KeyRoundInstUIIcon = wrapLucideIcon(Lucide.KeyRound) export const KeySquareInstUIIcon = wrapLucideIcon(Lucide.KeySquare) @@ -1197,6 +1318,7 @@ export const LaughInstUIIcon = wrapLucideIcon(Lucide.Laugh) export const LayersInstUIIcon = wrapLucideIcon(Lucide.Layers) export const Layers2InstUIIcon = wrapLucideIcon(Lucide.Layers2) export const Layers3InstUIIcon = wrapLucideIcon(Lucide.Layers3) +export const LayersPlusInstUIIcon = wrapLucideIcon(Lucide.LayersPlus) export const LayoutInstUIIcon = wrapLucideIcon(Lucide.Layout) export const LayoutDashboardInstUIIcon = wrapLucideIcon(Lucide.LayoutDashboard) export const LayoutGridInstUIIcon = wrapLucideIcon(Lucide.LayoutGrid) @@ -1216,6 +1338,7 @@ export const LigatureInstUIIcon = wrapLucideIcon(Lucide.Ligature) export const LightbulbInstUIIcon = wrapLucideIcon(Lucide.Lightbulb) export const LightbulbOffInstUIIcon = wrapLucideIcon(Lucide.LightbulbOff) export const LineChartInstUIIcon = wrapLucideIcon(Lucide.LineChart) +export const LineSquiggleInstUIIcon = wrapLucideIcon(Lucide.LineSquiggle) export const LinkInstUIIcon = wrapLucideIcon(Lucide.Link) export const Link2InstUIIcon = wrapLucideIcon(Lucide.Link2) export const Link2OffInstUIIcon = wrapLucideIcon(Lucide.Link2Off) @@ -1223,9 +1346,22 @@ export const LinkedinInstUIIcon = wrapLucideIcon(Lucide.Linkedin) export const ListInstUIIcon = wrapLucideIcon(Lucide.List) export const ListCheckInstUIIcon = wrapLucideIcon(Lucide.ListCheck) export const ListChecksInstUIIcon = wrapLucideIcon(Lucide.ListChecks) +export const ListChevronsDownUpInstUIIcon = wrapLucideIcon( + Lucide.ListChevronsDownUp +) +export const ListChevronsUpDownInstUIIcon = wrapLucideIcon( + Lucide.ListChevronsUpDown +) export const ListCollapseInstUIIcon = wrapLucideIcon(Lucide.ListCollapse) export const ListEndInstUIIcon = wrapLucideIcon(Lucide.ListEnd) export const ListFilterInstUIIcon = wrapLucideIcon(Lucide.ListFilter) +export const ListFilterPlusInstUIIcon = wrapLucideIcon(Lucide.ListFilterPlus) +export const ListIndentDecreaseInstUIIcon = wrapLucideIcon( + Lucide.ListIndentDecrease +) +export const ListIndentIncreaseInstUIIcon = wrapLucideIcon( + Lucide.ListIndentIncrease +) export const ListMinusInstUIIcon = wrapLucideIcon(Lucide.ListMinus) export const ListMusicInstUIIcon = wrapLucideIcon(Lucide.ListMusic) export const ListOrderedInstUIIcon = wrapLucideIcon(Lucide.ListOrdered) @@ -1243,6 +1379,7 @@ export const LoaderPinwheelInstUIIcon = wrapLucideIcon(Lucide.LoaderPinwheel) export const LocateInstUIIcon = wrapLucideIcon(Lucide.Locate) export const LocateFixedInstUIIcon = wrapLucideIcon(Lucide.LocateFixed) export const LocateOffInstUIIcon = wrapLucideIcon(Lucide.LocateOff) +export const LocationEditInstUIIcon = wrapLucideIcon(Lucide.LocationEdit) export const LockInstUIIcon = wrapLucideIcon(Lucide.Lock) export const LockKeyholeInstUIIcon = wrapLucideIcon(Lucide.LockKeyhole) export const LockKeyholeOpenInstUIIcon = wrapLucideIcon(Lucide.LockKeyholeOpen) @@ -1260,12 +1397,16 @@ export const MailMinusInstUIIcon = wrapLucideIcon(Lucide.MailMinus) export const MailOpenInstUIIcon = wrapLucideIcon(Lucide.MailOpen) export const MailPlusInstUIIcon = wrapLucideIcon(Lucide.MailPlus) export const MailQuestionInstUIIcon = wrapLucideIcon(Lucide.MailQuestion) +export const MailQuestionMarkInstUIIcon = wrapLucideIcon( + Lucide.MailQuestionMark +) export const MailSearchInstUIIcon = wrapLucideIcon(Lucide.MailSearch) export const MailWarningInstUIIcon = wrapLucideIcon(Lucide.MailWarning) export const MailXInstUIIcon = wrapLucideIcon(Lucide.MailX) export const MailboxInstUIIcon = wrapLucideIcon(Lucide.Mailbox) export const MailsInstUIIcon = wrapLucideIcon(Lucide.Mails) export const MapInstUIIcon = wrapLucideIcon(Lucide.Map) +export const MapMinusInstUIIcon = wrapLucideIcon(Lucide.MapMinus) export const MapPinInstUIIcon = wrapLucideIcon(Lucide.MapPin) export const MapPinCheckInstUIIcon = wrapLucideIcon(Lucide.MapPinCheck) export const MapPinCheckInsideInstUIIcon = wrapLucideIcon( @@ -1277,6 +1418,7 @@ export const MapPinMinusInsideInstUIIcon = wrapLucideIcon( Lucide.MapPinMinusInside ) export const MapPinOffInstUIIcon = wrapLucideIcon(Lucide.MapPinOff) +export const MapPinPenInstUIIcon = wrapLucideIcon(Lucide.MapPinPen) export const MapPinPlusInstUIIcon = wrapLucideIcon(Lucide.MapPinPlus) export const MapPinPlusInsideInstUIIcon = wrapLucideIcon( Lucide.MapPinPlusInside @@ -1284,6 +1426,9 @@ export const MapPinPlusInsideInstUIIcon = wrapLucideIcon( export const MapPinXInstUIIcon = wrapLucideIcon(Lucide.MapPinX) export const MapPinXInsideInstUIIcon = wrapLucideIcon(Lucide.MapPinXInside) export const MapPinnedInstUIIcon = wrapLucideIcon(Lucide.MapPinned) +export const MapPlusInstUIIcon = wrapLucideIcon(Lucide.MapPlus) +export const MarsInstUIIcon = wrapLucideIcon(Lucide.Mars) +export const MarsStrokeInstUIIcon = wrapLucideIcon(Lucide.MarsStroke) export const MartiniInstUIIcon = wrapLucideIcon(Lucide.Martini) export const MaximizeInstUIIcon = wrapLucideIcon(Lucide.Maximize) export const Maximize2InstUIIcon = wrapLucideIcon(Lucide.Maximize2) @@ -1317,6 +1462,9 @@ export const MessageCirclePlusInstUIIcon = wrapLucideIcon( export const MessageCircleQuestionInstUIIcon = wrapLucideIcon( Lucide.MessageCircleQuestion ) +export const MessageCircleQuestionMarkInstUIIcon = wrapLucideIcon( + Lucide.MessageCircleQuestionMark +) export const MessageCircleReplyInstUIIcon = wrapLucideIcon( Lucide.MessageCircleReply ) @@ -1386,6 +1534,7 @@ export const MinusCircleInstUIIcon = wrapLucideIcon(Lucide.MinusCircle) export const MinusSquareInstUIIcon = wrapLucideIcon(Lucide.MinusSquare) export const MonitorInstUIIcon = wrapLucideIcon(Lucide.Monitor) export const MonitorCheckInstUIIcon = wrapLucideIcon(Lucide.MonitorCheck) +export const MonitorCloudInstUIIcon = wrapLucideIcon(Lucide.MonitorCloud) export const MonitorCogInstUIIcon = wrapLucideIcon(Lucide.MonitorCog) export const MonitorDotInstUIIcon = wrapLucideIcon(Lucide.MonitorDot) export const MonitorDownInstUIIcon = wrapLucideIcon(Lucide.MonitorDown) @@ -1403,12 +1552,16 @@ export const MoonInstUIIcon = wrapLucideIcon(Lucide.Moon) export const MoonStarInstUIIcon = wrapLucideIcon(Lucide.MoonStar) export const MoreHorizontalInstUIIcon = wrapLucideIcon(Lucide.MoreHorizontal) export const MoreVerticalInstUIIcon = wrapLucideIcon(Lucide.MoreVertical) +export const MotorbikeInstUIIcon = wrapLucideIcon(Lucide.Motorbike) export const MountainInstUIIcon = wrapLucideIcon(Lucide.Mountain) export const MountainSnowInstUIIcon = wrapLucideIcon(Lucide.MountainSnow) export const MouseInstUIIcon = wrapLucideIcon(Lucide.Mouse) export const MouseOffInstUIIcon = wrapLucideIcon(Lucide.MouseOff) export const MousePointerInstUIIcon = wrapLucideIcon(Lucide.MousePointer) export const MousePointer2InstUIIcon = wrapLucideIcon(Lucide.MousePointer2) +export const MousePointer2OffInstUIIcon = wrapLucideIcon( + Lucide.MousePointer2Off +) export const MousePointerBanInstUIIcon = wrapLucideIcon(Lucide.MousePointerBan) export const MousePointerClickInstUIIcon = wrapLucideIcon( Lucide.MousePointerClick @@ -1442,6 +1595,7 @@ export const NavigationOffInstUIIcon = wrapLucideIcon(Lucide.NavigationOff) export const NetworkInstUIIcon = wrapLucideIcon(Lucide.Network) export const NewspaperInstUIIcon = wrapLucideIcon(Lucide.Newspaper) export const NfcInstUIIcon = wrapLucideIcon(Lucide.Nfc) +export const NonBinaryInstUIIcon = wrapLucideIcon(Lucide.NonBinary) export const NotebookInstUIIcon = wrapLucideIcon(Lucide.Notebook) export const NotebookPenInstUIIcon = wrapLucideIcon(Lucide.NotebookPen) export const NotebookTabsInstUIIcon = wrapLucideIcon(Lucide.NotebookTabs) @@ -1479,6 +1633,7 @@ export const PaintbrushVerticalInstUIIcon = wrapLucideIcon( ) export const PaletteInstUIIcon = wrapLucideIcon(Lucide.Palette) export const PalmtreeInstUIIcon = wrapLucideIcon(Lucide.Palmtree) +export const PandaInstUIIcon = wrapLucideIcon(Lucide.Panda) export const PanelBottomInstUIIcon = wrapLucideIcon(Lucide.PanelBottom) export const PanelBottomCloseInstUIIcon = wrapLucideIcon( Lucide.PanelBottomClose @@ -1497,6 +1652,9 @@ export const PanelLeftInactiveInstUIIcon = wrapLucideIcon( Lucide.PanelLeftInactive ) export const PanelLeftOpenInstUIIcon = wrapLucideIcon(Lucide.PanelLeftOpen) +export const PanelLeftRightDashedInstUIIcon = wrapLucideIcon( + Lucide.PanelLeftRightDashed +) export const PanelRightInstUIIcon = wrapLucideIcon(Lucide.PanelRight) export const PanelRightCloseInstUIIcon = wrapLucideIcon(Lucide.PanelRightClose) export const PanelRightDashedInstUIIcon = wrapLucideIcon( @@ -1507,6 +1665,9 @@ export const PanelRightInactiveInstUIIcon = wrapLucideIcon( ) export const PanelRightOpenInstUIIcon = wrapLucideIcon(Lucide.PanelRightOpen) export const PanelTopInstUIIcon = wrapLucideIcon(Lucide.PanelTop) +export const PanelTopBottomDashedInstUIIcon = wrapLucideIcon( + Lucide.PanelTopBottomDashed +) export const PanelTopCloseInstUIIcon = wrapLucideIcon(Lucide.PanelTopClose) export const PanelTopDashedInstUIIcon = wrapLucideIcon(Lucide.PanelTopDashed) export const PanelTopInactiveInstUIIcon = wrapLucideIcon( @@ -1650,9 +1811,16 @@ export const ReceiptSwissFrancInstUIIcon = wrapLucideIcon( Lucide.ReceiptSwissFranc ) export const ReceiptTextInstUIIcon = wrapLucideIcon(Lucide.ReceiptText) +export const ReceiptTurkishLiraInstUIIcon = wrapLucideIcon( + Lucide.ReceiptTurkishLira +) +export const RectangleCircleInstUIIcon = wrapLucideIcon(Lucide.RectangleCircle) export const RectangleEllipsisInstUIIcon = wrapLucideIcon( Lucide.RectangleEllipsis ) +export const RectangleGogglesInstUIIcon = wrapLucideIcon( + Lucide.RectangleGoggles +) export const RectangleHorizontalInstUIIcon = wrapLucideIcon( Lucide.RectangleHorizontal ) @@ -1684,9 +1852,11 @@ export const RibbonInstUIIcon = wrapLucideIcon(Lucide.Ribbon) export const RocketInstUIIcon = wrapLucideIcon(Lucide.Rocket) export const RockingChairInstUIIcon = wrapLucideIcon(Lucide.RockingChair) export const RollerCoasterInstUIIcon = wrapLucideIcon(Lucide.RollerCoaster) +export const RoseInstUIIcon = wrapLucideIcon(Lucide.Rose) export const Rotate3DInstUIIcon = wrapLucideIcon(Lucide.Rotate3D) export const Rotate3dInstUIIcon = wrapLucideIcon(Lucide.Rotate3d) export const RotateCcwInstUIIcon = wrapLucideIcon(Lucide.RotateCcw) +export const RotateCcwKeyInstUIIcon = wrapLucideIcon(Lucide.RotateCcwKey) export const RotateCcwSquareInstUIIcon = wrapLucideIcon(Lucide.RotateCcwSquare) export const RotateCwInstUIIcon = wrapLucideIcon(Lucide.RotateCw) export const RotateCwSquareInstUIIcon = wrapLucideIcon(Lucide.RotateCwSquare) @@ -1699,12 +1869,16 @@ export const Rows3InstUIIcon = wrapLucideIcon(Lucide.Rows3) export const Rows4InstUIIcon = wrapLucideIcon(Lucide.Rows4) export const RssInstUIIcon = wrapLucideIcon(Lucide.Rss) export const RulerInstUIIcon = wrapLucideIcon(Lucide.Ruler) +export const RulerDimensionLineInstUIIcon = wrapLucideIcon( + Lucide.RulerDimensionLine +) export const RussianRubleInstUIIcon = wrapLucideIcon(Lucide.RussianRuble) export const SailboatInstUIIcon = wrapLucideIcon(Lucide.Sailboat) export const SaladInstUIIcon = wrapLucideIcon(Lucide.Salad) export const SandwichInstUIIcon = wrapLucideIcon(Lucide.Sandwich) export const SatelliteInstUIIcon = wrapLucideIcon(Lucide.Satellite) export const SatelliteDishInstUIIcon = wrapLucideIcon(Lucide.SatelliteDish) +export const SaudiRiyalInstUIIcon = wrapLucideIcon(Lucide.SaudiRiyal) export const SaveInstUIIcon = wrapLucideIcon(Lucide.Save) export const SaveAllInstUIIcon = wrapLucideIcon(Lucide.SaveAll) export const SaveOffInstUIIcon = wrapLucideIcon(Lucide.SaveOff) @@ -1716,6 +1890,7 @@ export const ScanInstUIIcon = wrapLucideIcon(Lucide.Scan) export const ScanBarcodeInstUIIcon = wrapLucideIcon(Lucide.ScanBarcode) export const ScanEyeInstUIIcon = wrapLucideIcon(Lucide.ScanEye) export const ScanFaceInstUIIcon = wrapLucideIcon(Lucide.ScanFace) +export const ScanHeartInstUIIcon = wrapLucideIcon(Lucide.ScanHeart) export const ScanLineInstUIIcon = wrapLucideIcon(Lucide.ScanLine) export const ScanQrCodeInstUIIcon = wrapLucideIcon(Lucide.ScanQrCode) export const ScanSearchInstUIIcon = wrapLucideIcon(Lucide.ScanSearch) @@ -1731,11 +1906,13 @@ export const ScissorsSquareInstUIIcon = wrapLucideIcon(Lucide.ScissorsSquare) export const ScissorsSquareDashedBottomInstUIIcon = wrapLucideIcon( Lucide.ScissorsSquareDashedBottom ) +export const ScooterInstUIIcon = wrapLucideIcon(Lucide.Scooter) export const ScreenShareInstUIIcon = wrapLucideIcon(Lucide.ScreenShare) export const ScreenShareOffInstUIIcon = wrapLucideIcon(Lucide.ScreenShareOff) export const ScrollInstUIIcon = wrapLucideIcon(Lucide.Scroll) export const ScrollTextInstUIIcon = wrapLucideIcon(Lucide.ScrollText) export const SearchInstUIIcon = wrapLucideIcon(Lucide.Search) +export const SearchAlertInstUIIcon = wrapLucideIcon(Lucide.SearchAlert) export const SearchCheckInstUIIcon = wrapLucideIcon(Lucide.SearchCheck) export const SearchCodeInstUIIcon = wrapLucideIcon(Lucide.SearchCode) export const SearchSlashInstUIIcon = wrapLucideIcon(Lucide.SearchSlash) @@ -1773,6 +1950,10 @@ export const ShieldMinusInstUIIcon = wrapLucideIcon(Lucide.ShieldMinus) export const ShieldOffInstUIIcon = wrapLucideIcon(Lucide.ShieldOff) export const ShieldPlusInstUIIcon = wrapLucideIcon(Lucide.ShieldPlus) export const ShieldQuestionInstUIIcon = wrapLucideIcon(Lucide.ShieldQuestion) +export const ShieldQuestionMarkInstUIIcon = wrapLucideIcon( + Lucide.ShieldQuestionMark +) +export const ShieldUserInstUIIcon = wrapLucideIcon(Lucide.ShieldUser) export const ShieldXInstUIIcon = wrapLucideIcon(Lucide.ShieldX) export const ShipInstUIIcon = wrapLucideIcon(Lucide.Ship) export const ShipWheelInstUIIcon = wrapLucideIcon(Lucide.ShipWheel) @@ -1782,6 +1963,8 @@ export const ShoppingBasketInstUIIcon = wrapLucideIcon(Lucide.ShoppingBasket) export const ShoppingCartInstUIIcon = wrapLucideIcon(Lucide.ShoppingCart) export const ShovelInstUIIcon = wrapLucideIcon(Lucide.Shovel) export const ShowerHeadInstUIIcon = wrapLucideIcon(Lucide.ShowerHead) +export const ShredderInstUIIcon = wrapLucideIcon(Lucide.Shredder) +export const ShrimpInstUIIcon = wrapLucideIcon(Lucide.Shrimp) export const ShrinkInstUIIcon = wrapLucideIcon(Lucide.Shrink) export const ShrubInstUIIcon = wrapLucideIcon(Lucide.Shrub) export const ShuffleInstUIIcon = wrapLucideIcon(Lucide.Shuffle) @@ -1820,7 +2003,11 @@ export const SmileInstUIIcon = wrapLucideIcon(Lucide.Smile) export const SmilePlusInstUIIcon = wrapLucideIcon(Lucide.SmilePlus) export const SnailInstUIIcon = wrapLucideIcon(Lucide.Snail) export const SnowflakeInstUIIcon = wrapLucideIcon(Lucide.Snowflake) +export const SoapDispenserDropletInstUIIcon = wrapLucideIcon( + Lucide.SoapDispenserDroplet +) export const SofaInstUIIcon = wrapLucideIcon(Lucide.Sofa) +export const SolarPanelInstUIIcon = wrapLucideIcon(Lucide.SolarPanel) export const SortAscInstUIIcon = wrapLucideIcon(Lucide.SortAsc) export const SortDescInstUIIcon = wrapLucideIcon(Lucide.SortDesc) export const SoupInstUIIcon = wrapLucideIcon(Lucide.Soup) @@ -1833,6 +2020,7 @@ export const SpeechInstUIIcon = wrapLucideIcon(Lucide.Speech) export const SpellCheckInstUIIcon = wrapLucideIcon(Lucide.SpellCheck) export const SpellCheck2InstUIIcon = wrapLucideIcon(Lucide.SpellCheck2) export const SplineInstUIIcon = wrapLucideIcon(Lucide.Spline) +export const SplinePointerInstUIIcon = wrapLucideIcon(Lucide.SplinePointer) export const SplitInstUIIcon = wrapLucideIcon(Lucide.Split) export const SplitSquareHorizontalInstUIIcon = wrapLucideIcon( Lucide.SplitSquareHorizontal @@ -1840,6 +2028,8 @@ export const SplitSquareHorizontalInstUIIcon = wrapLucideIcon( export const SplitSquareVerticalInstUIIcon = wrapLucideIcon( Lucide.SplitSquareVertical ) +export const SpoolInstUIIcon = wrapLucideIcon(Lucide.Spool) +export const SpotlightInstUIIcon = wrapLucideIcon(Lucide.Spotlight) export const SprayCanInstUIIcon = wrapLucideIcon(Lucide.SprayCan) export const SproutInstUIIcon = wrapLucideIcon(Lucide.Sprout) export const SquareInstUIIcon = wrapLucideIcon(Lucide.Square) @@ -1907,6 +2097,9 @@ export const SquareDashedKanbanInstUIIcon = wrapLucideIcon( export const SquareDashedMousePointerInstUIIcon = wrapLucideIcon( Lucide.SquareDashedMousePointer ) +export const SquareDashedTopSolidInstUIIcon = wrapLucideIcon( + Lucide.SquareDashedTopSolid +) export const SquareDivideInstUIIcon = wrapLucideIcon(Lucide.SquareDivide) export const SquareDotInstUIIcon = wrapLucideIcon(Lucide.SquareDot) export const SquareEqualInstUIIcon = wrapLucideIcon(Lucide.SquareEqual) @@ -1926,6 +2119,7 @@ export const SquareParkingInstUIIcon = wrapLucideIcon(Lucide.SquareParking) export const SquareParkingOffInstUIIcon = wrapLucideIcon( Lucide.SquareParkingOff ) +export const SquarePauseInstUIIcon = wrapLucideIcon(Lucide.SquarePause) export const SquarePenInstUIIcon = wrapLucideIcon(Lucide.SquarePen) export const SquarePercentInstUIIcon = wrapLucideIcon(Lucide.SquarePercent) export const SquarePiInstUIIcon = wrapLucideIcon(Lucide.SquarePi) @@ -1934,6 +2128,9 @@ export const SquarePlayInstUIIcon = wrapLucideIcon(Lucide.SquarePlay) export const SquarePlusInstUIIcon = wrapLucideIcon(Lucide.SquarePlus) export const SquarePowerInstUIIcon = wrapLucideIcon(Lucide.SquarePower) export const SquareRadicalInstUIIcon = wrapLucideIcon(Lucide.SquareRadical) +export const SquareRoundCornerInstUIIcon = wrapLucideIcon( + Lucide.SquareRoundCorner +) export const SquareScissorsInstUIIcon = wrapLucideIcon(Lucide.SquareScissors) export const SquareSigmaInstUIIcon = wrapLucideIcon(Lucide.SquareSigma) export const SquareSlashInstUIIcon = wrapLucideIcon(Lucide.SquareSlash) @@ -1945,11 +2142,20 @@ export const SquareSplitVerticalInstUIIcon = wrapLucideIcon( ) export const SquareSquareInstUIIcon = wrapLucideIcon(Lucide.SquareSquare) export const SquareStackInstUIIcon = wrapLucideIcon(Lucide.SquareStack) +export const SquareStarInstUIIcon = wrapLucideIcon(Lucide.SquareStar) +export const SquareStopInstUIIcon = wrapLucideIcon(Lucide.SquareStop) export const SquareTerminalInstUIIcon = wrapLucideIcon(Lucide.SquareTerminal) export const SquareUserInstUIIcon = wrapLucideIcon(Lucide.SquareUser) export const SquareUserRoundInstUIIcon = wrapLucideIcon(Lucide.SquareUserRound) export const SquareXInstUIIcon = wrapLucideIcon(Lucide.SquareX) +export const SquaresExcludeInstUIIcon = wrapLucideIcon(Lucide.SquaresExclude) +export const SquaresIntersectInstUIIcon = wrapLucideIcon( + Lucide.SquaresIntersect +) +export const SquaresSubtractInstUIIcon = wrapLucideIcon(Lucide.SquaresSubtract) +export const SquaresUniteInstUIIcon = wrapLucideIcon(Lucide.SquaresUnite) export const SquircleInstUIIcon = wrapLucideIcon(Lucide.Squircle) +export const SquircleDashedInstUIIcon = wrapLucideIcon(Lucide.SquircleDashed) export const SquirrelInstUIIcon = wrapLucideIcon(Lucide.Squirrel) export const StampInstUIIcon = wrapLucideIcon(Lucide.Stamp) export const StarInstUIIcon = wrapLucideIcon(Lucide.Star) @@ -1991,6 +2197,7 @@ export const TableCellsSplitInstUIIcon = wrapLucideIcon(Lucide.TableCellsSplit) export const TableColumnsSplitInstUIIcon = wrapLucideIcon( Lucide.TableColumnsSplit ) +export const TableConfigInstUIIcon = wrapLucideIcon(Lucide.TableConfig) export const TableOfContentsInstUIIcon = wrapLucideIcon(Lucide.TableOfContents) export const TablePropertiesInstUIIcon = wrapLucideIcon(Lucide.TableProperties) export const TableRowsSplitInstUIIcon = wrapLucideIcon(Lucide.TableRowsSplit) @@ -2020,12 +2227,20 @@ export const TestTubeDiagonalInstUIIcon = wrapLucideIcon( ) export const TestTubesInstUIIcon = wrapLucideIcon(Lucide.TestTubes) export const TextInstUIIcon = wrapLucideIcon(Lucide.Text) +export const TextAlignCenterInstUIIcon = wrapLucideIcon(Lucide.TextAlignCenter) +export const TextAlignEndInstUIIcon = wrapLucideIcon(Lucide.TextAlignEnd) +export const TextAlignJustifyInstUIIcon = wrapLucideIcon( + Lucide.TextAlignJustify +) +export const TextAlignStartInstUIIcon = wrapLucideIcon(Lucide.TextAlignStart) export const TextCursorInstUIIcon = wrapLucideIcon(Lucide.TextCursor) export const TextCursorInputInstUIIcon = wrapLucideIcon(Lucide.TextCursorInput) +export const TextInitialInstUIIcon = wrapLucideIcon(Lucide.TextInitial) export const TextQuoteInstUIIcon = wrapLucideIcon(Lucide.TextQuote) export const TextSearchInstUIIcon = wrapLucideIcon(Lucide.TextSearch) export const TextSelectInstUIIcon = wrapLucideIcon(Lucide.TextSelect) export const TextSelectionInstUIIcon = wrapLucideIcon(Lucide.TextSelection) +export const TextWrapInstUIIcon = wrapLucideIcon(Lucide.TextWrap) export const TheaterInstUIIcon = wrapLucideIcon(Lucide.Theater) export const ThermometerInstUIIcon = wrapLucideIcon(Lucide.Thermometer) export const ThermometerSnowflakeInstUIIcon = wrapLucideIcon( @@ -2049,6 +2264,7 @@ export const TimerResetInstUIIcon = wrapLucideIcon(Lucide.TimerReset) export const ToggleLeftInstUIIcon = wrapLucideIcon(Lucide.ToggleLeft) export const ToggleRightInstUIIcon = wrapLucideIcon(Lucide.ToggleRight) export const ToiletInstUIIcon = wrapLucideIcon(Lucide.Toilet) +export const ToolCaseInstUIIcon = wrapLucideIcon(Lucide.ToolCase) export const TornadoInstUIIcon = wrapLucideIcon(Lucide.Tornado) export const TorusInstUIIcon = wrapLucideIcon(Lucide.Torus) export const TouchpadInstUIIcon = wrapLucideIcon(Lucide.Touchpad) @@ -2064,6 +2280,7 @@ export const TrainFrontTunnelInstUIIcon = wrapLucideIcon( ) export const TrainTrackInstUIIcon = wrapLucideIcon(Lucide.TrainTrack) export const TramFrontInstUIIcon = wrapLucideIcon(Lucide.TramFront) +export const TransgenderInstUIIcon = wrapLucideIcon(Lucide.Transgender) export const TrashInstUIIcon = wrapLucideIcon(Lucide.Trash) export const Trash2InstUIIcon = wrapLucideIcon(Lucide.Trash2) export const TreeDeciduousInstUIIcon = wrapLucideIcon(Lucide.TreeDeciduous) @@ -2076,9 +2293,13 @@ export const TrendingUpInstUIIcon = wrapLucideIcon(Lucide.TrendingUp) export const TrendingUpDownInstUIIcon = wrapLucideIcon(Lucide.TrendingUpDown) export const TriangleInstUIIcon = wrapLucideIcon(Lucide.Triangle) export const TriangleAlertInstUIIcon = wrapLucideIcon(Lucide.TriangleAlert) +export const TriangleDashedInstUIIcon = wrapLucideIcon(Lucide.TriangleDashed) export const TriangleRightInstUIIcon = wrapLucideIcon(Lucide.TriangleRight) export const TrophyInstUIIcon = wrapLucideIcon(Lucide.Trophy) export const TruckInstUIIcon = wrapLucideIcon(Lucide.Truck) +export const TruckElectricInstUIIcon = wrapLucideIcon(Lucide.TruckElectric) +export const TurkishLiraInstUIIcon = wrapLucideIcon(Lucide.TurkishLira) +export const TurntableInstUIIcon = wrapLucideIcon(Lucide.Turntable) export const TurtleInstUIIcon = wrapLucideIcon(Lucide.Turtle) export const TvInstUIIcon = wrapLucideIcon(Lucide.Tv) export const Tv2InstUIIcon = wrapLucideIcon(Lucide.Tv2) @@ -2116,6 +2337,7 @@ export const UserCircleInstUIIcon = wrapLucideIcon(Lucide.UserCircle) export const UserCircle2InstUIIcon = wrapLucideIcon(Lucide.UserCircle2) export const UserCogInstUIIcon = wrapLucideIcon(Lucide.UserCog) export const UserCog2InstUIIcon = wrapLucideIcon(Lucide.UserCog2) +export const UserLockInstUIIcon = wrapLucideIcon(Lucide.UserLock) export const UserMinusInstUIIcon = wrapLucideIcon(Lucide.UserMinus) export const UserMinus2InstUIIcon = wrapLucideIcon(Lucide.UserMinus2) export const UserPenInstUIIcon = wrapLucideIcon(Lucide.UserPen) @@ -2132,6 +2354,7 @@ export const UserRoundXInstUIIcon = wrapLucideIcon(Lucide.UserRoundX) export const UserSearchInstUIIcon = wrapLucideIcon(Lucide.UserSearch) export const UserSquareInstUIIcon = wrapLucideIcon(Lucide.UserSquare) export const UserSquare2InstUIIcon = wrapLucideIcon(Lucide.UserSquare2) +export const UserStarInstUIIcon = wrapLucideIcon(Lucide.UserStar) export const UserXInstUIIcon = wrapLucideIcon(Lucide.UserX) export const UserX2InstUIIcon = wrapLucideIcon(Lucide.UserX2) export const UsersInstUIIcon = wrapLucideIcon(Lucide.Users) @@ -2140,10 +2363,14 @@ export const UsersRoundInstUIIcon = wrapLucideIcon(Lucide.UsersRound) export const UtensilsInstUIIcon = wrapLucideIcon(Lucide.Utensils) export const UtensilsCrossedInstUIIcon = wrapLucideIcon(Lucide.UtensilsCrossed) export const UtilityPoleInstUIIcon = wrapLucideIcon(Lucide.UtilityPole) +export const VanInstUIIcon = wrapLucideIcon(Lucide.Van) export const VariableInstUIIcon = wrapLucideIcon(Lucide.Variable) export const VaultInstUIIcon = wrapLucideIcon(Lucide.Vault) +export const VectorSquareInstUIIcon = wrapLucideIcon(Lucide.VectorSquare) export const VeganInstUIIcon = wrapLucideIcon(Lucide.Vegan) export const VenetianMaskInstUIIcon = wrapLucideIcon(Lucide.VenetianMask) +export const VenusInstUIIcon = wrapLucideIcon(Lucide.Venus) +export const VenusAndMarsInstUIIcon = wrapLucideIcon(Lucide.VenusAndMars) export const VerifiedInstUIIcon = wrapLucideIcon(Lucide.Verified) export const VibrateInstUIIcon = wrapLucideIcon(Lucide.Vibrate) export const VibrateOffInstUIIcon = wrapLucideIcon(Lucide.VibrateOff) @@ -2171,18 +2398,25 @@ export const WarehouseInstUIIcon = wrapLucideIcon(Lucide.Warehouse) export const WashingMachineInstUIIcon = wrapLucideIcon(Lucide.WashingMachine) export const WatchInstUIIcon = wrapLucideIcon(Lucide.Watch) export const WavesInstUIIcon = wrapLucideIcon(Lucide.Waves) +export const WavesArrowDownInstUIIcon = wrapLucideIcon(Lucide.WavesArrowDown) +export const WavesArrowUpInstUIIcon = wrapLucideIcon(Lucide.WavesArrowUp) +export const WavesLadderInstUIIcon = wrapLucideIcon(Lucide.WavesLadder) export const WaypointsInstUIIcon = wrapLucideIcon(Lucide.Waypoints) export const WebcamInstUIIcon = wrapLucideIcon(Lucide.Webcam) export const WebhookInstUIIcon = wrapLucideIcon(Lucide.Webhook) export const WebhookOffInstUIIcon = wrapLucideIcon(Lucide.WebhookOff) export const WeightInstUIIcon = wrapLucideIcon(Lucide.Weight) +export const WeightTildeInstUIIcon = wrapLucideIcon(Lucide.WeightTilde) export const WheatInstUIIcon = wrapLucideIcon(Lucide.Wheat) export const WheatOffInstUIIcon = wrapLucideIcon(Lucide.WheatOff) export const WholeWordInstUIIcon = wrapLucideIcon(Lucide.WholeWord) export const WifiInstUIIcon = wrapLucideIcon(Lucide.Wifi) +export const WifiCogInstUIIcon = wrapLucideIcon(Lucide.WifiCog) export const WifiHighInstUIIcon = wrapLucideIcon(Lucide.WifiHigh) export const WifiLowInstUIIcon = wrapLucideIcon(Lucide.WifiLow) export const WifiOffInstUIIcon = wrapLucideIcon(Lucide.WifiOff) +export const WifiPenInstUIIcon = wrapLucideIcon(Lucide.WifiPen) +export const WifiSyncInstUIIcon = wrapLucideIcon(Lucide.WifiSync) export const WifiZeroInstUIIcon = wrapLucideIcon(Lucide.WifiZero) export const WindInstUIIcon = wrapLucideIcon(Lucide.Wind) export const WindArrowDownInstUIIcon = wrapLucideIcon(Lucide.WindArrowDown) diff --git a/packages/ui-icons-lucide/src/wrapLucideIcon/index.tsx b/packages/ui-icons-lucide/src/wrapLucideIcon/index.tsx index a877aede31..e89e293cc1 100644 --- a/packages/ui-icons-lucide/src/wrapLucideIcon/index.tsx +++ b/packages/ui-icons-lucide/src/wrapLucideIcon/index.tsx @@ -22,25 +22,30 @@ * SOFTWARE. */ -import { useStyle, useTheme } from '@instructure/emotion' -import { px } from '@instructure/ui-utils' +import React, { useId, useContext } from 'react' +import { useStyle } from '@instructure/emotion' import { passthroughProps } from '@instructure/ui-react-utils' -import type { Theme } from '@instructure/ui-themes' import type { LucideIcon } from 'lucide-react' -import type { LucideIconWrapperProps, InstUIIconOwnProps } from './props' +import { IconPropsContext } from '../IconPropsProvider' + +import type { LucideIconWrapperProps } from './props' import generateStyle from './styles' /** * Wraps a Lucide icon with InstUI theming, RTL support, and semantic sizing. - * Supports both InstUI semantic props (size="lg", color="baseColor") and - * native Lucide props (size={24}, color="#ff0000"). + * Only accepts InstUI semantic tokens (size="lg", color="baseColor"). + * Stroke width is automatically derived from size for consistent visual weight. + * Numeric and custom CSS values are not supported. */ -export function wrapLucideIcon(Icon: LucideIcon): LucideIcon { +export function wrapLucideIcon( + Icon: LucideIcon +): React.ComponentType { + const iconDisplayName = `wrapLucideIcon(${Icon.displayName})` + const WrappedIcon = (props: LucideIconWrapperProps) => { const { size, - strokeWidth, color, rotate = '0', bidirectional = true, @@ -48,14 +53,15 @@ export function wrapLucideIcon(Icon: LucideIcon): LucideIcon { title, elementRef, themeOverride, - absoluteStrokeWidth, - className, - style, ...rest } = props - const theme = useTheme() as Theme - const iconTheme = theme?.newTheme?.components?.Icon + // Get icon props from context (if available) + const contextProps = useContext(IconPropsContext) + + // Merge props: context props take precedence over direct props + const finalSize = contextProps?.size ?? size + const finalColor = contextProps?.color ?? color const handleElementRef = (el: SVGSVGElement | null) => { if (typeof elementRef === 'function') { @@ -63,78 +69,21 @@ export function wrapLucideIcon(Icon: LucideIcon): LucideIcon { } } - // Convert semantic size to pixels for Lucide - let numericSize: number | undefined - let semanticSize: string | undefined - if (typeof size === 'string' && iconTheme) { - // Construct theme property name (e.g., 'xs' -> 'sizeXs') - const propName = `size${size.charAt(0).toUpperCase()}${size.slice( - 1 - )}` as keyof typeof iconTheme - if (propName in iconTheme) { - // Semantic size token from theme - semanticSize = size - numericSize = px(iconTheme[propName] as string) - } - } else if (typeof size === 'number') { - numericSize = size - } - - // Convert semantic strokeWidth to pixels for Lucide - let numericStrokeWidth: number | string | undefined - if (typeof strokeWidth === 'string' && iconTheme) { - // Construct theme property name (e.g., 'xs' -> 'strokeWidthXs') - const propName = `strokeWidth${strokeWidth - .charAt(0) - .toUpperCase()}${strokeWidth.slice(1)}` as keyof typeof iconTheme - if (propName in iconTheme) { - // Semantic stroke width token from theme - numericStrokeWidth = px(iconTheme[propName] as string) - } else { - // Not a semantic token, use as-is (custom string value) - numericStrokeWidth = strokeWidth - } - } else { - // Numeric value (custom stroke width) - numericStrokeWidth = strokeWidth - } - - // Determine if color is semantic (theme token) or custom CSS - let colorValue: string | undefined - let customColor: string | undefined - if (color) { - if (color === 'inherit') { - colorValue = color - } else if ( - iconTheme && - color in iconTheme && - !color.startsWith('size') && - !color.startsWith('strokeWidth') && - color !== 'dark' - ) { - // Semantic color token from theme (exclude size/strokeWidth/dark properties) - colorValue = color - } else { - // Custom CSS color (e.g., "#ff0000", "rgb(255, 0, 0)") - customColor = color - } - } - const styles = useStyle({ - componentId: 'Icon' as const, + componentId: 'Icon', generateStyle, themeOverride, params: { - size: semanticSize as InstUIIconOwnProps['size'], - color: colorValue, + size: finalSize, + color: finalColor, rotate, bidirectional, inline }, - displayName: `LucideIcon(${Icon.displayName || Icon.name})` + displayName: iconDisplayName }) - const accessibilityProps: Record = {} + const accessibilityProps: Record = {} if (title) { accessibilityProps['aria-label'] = title accessibilityProps['role'] = 'img' @@ -143,26 +92,70 @@ export function wrapLucideIcon(Icon: LucideIcon): LucideIcon { accessibilityProps['role'] = 'presentation' } + const gradientId = useId() + + // AI Gradient Implementation: + // SVG gradients must be defined BEFORE they're referenced. Since Lucide renders + // icon paths before any children we pass, we inject the gradient in a separate + // hidden SVG element that comes BEFORE the icon in the DOM. We use + // gradientUnits="userSpaceOnUse" with coordinates (0,0) to (24,24) matching + // Lucide's viewBox, ensuring one gradient spans the entire icon space rather + // than scaling separately for each shape (which causes small elements to lose + // gradient visibility). The icon then references this gradient via stroke="url(#id)". + if (styles.gradientColors) { + // Use viewBox coordinates for gradient (Lucide icons use 0 0 24 24 viewBox) + const gradientSize = 24 + + return ( + + {/* Hidden SVG to define the gradient - must come before the icon uses it */} + + + + + + + + + + + ) + } + + // Normal rendering (non-gradient) return ( - + ) } - WrappedIcon.displayName = `wrapLucideIcon(${Icon.displayName || Icon.name})` + WrappedIcon.displayName = iconDisplayName - return WrappedIcon as LucideIcon + return WrappedIcon } - -export type { LucideIconWrapperProps, InstUIIconOwnProps } -export { default as generateStyle } from './styles' diff --git a/packages/ui-icons-lucide/src/wrapLucideIcon/props.ts b/packages/ui-icons-lucide/src/wrapLucideIcon/props.ts index 7b0968e803..6d87098cb0 100644 --- a/packages/ui-icons-lucide/src/wrapLucideIcon/props.ts +++ b/packages/ui-icons-lucide/src/wrapLucideIcon/props.ts @@ -22,53 +22,118 @@ * SOFTWARE. */ -import type { LucideProps } from 'lucide-react' import type { ComponentStyle, ThemeOverrideValue } from '@instructure/emotion' -import type { NewComponentTypes } from '@instructure/ui-themes' import type { OtherHTMLAttributes } from '@instructure/shared-types' /** - * Extract size tokens from Icon theme (sizeXs, sizeSm, etc.) - * and transform to lowercase literals ('xs', 'sm', etc.) + * SVGIcon size tokens (legacy) - DEPRECATED */ -type ExtractSizeTokens = { - [K in keyof T]: K extends `size${infer Size}` ? Lowercase : never -}[keyof T] +type SVGIconSizeToken = 'x-small' | 'small' | 'medium' | 'large' | 'x-large' /** - * Extract strokeWidth tokens from Icon theme (strokeWidthXs, etc.) - * and transform to lowercase literals ('xs', 'sm', etc.) + * SVGIcon color tokens (legacy) - DEPRECATED */ -type ExtractStrokeWidthTokens = { - [K in keyof T]: K extends `strokeWidth${infer Size}` ? Lowercase : never -}[keyof T] +type LegacyColorTokens = + | 'primary' + | 'secondary' + | 'primary-inverse' + | 'secondary-inverse' + | 'success' + | 'error' + | 'alert' + | 'warning' + | 'brand' + | 'auto' /** - * Extract color tokens from Icon theme - * (all properties except size/strokeWidth and 'dark') + * Semantic size tokens for icons - includes SVGIcon legacy tokens, they are DEPRECATED and will be deleted, DON'T USE THEM. */ -type ExtractColorTokens = Exclude< - keyof T, - `size${string}` | `strokeWidth${string}` | 'dark' -> +type IconSizeToken = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | SVGIconSizeToken -type IconSizeToken = ExtractSizeTokens -type IconStrokeWidthToken = ExtractStrokeWidthTokens -type IconColorToken = ExtractColorTokens +/** + * Semantic color tokens from Icon theme + */ +type IconColorToken = + | 'baseColor' + | 'mutedColor' + | 'successColor' + | 'errorColor' + | 'warningColor' + | 'infoColor' + | 'onColor' + | 'inverseColor' + | 'disabledBaseColor' + | 'disabledOnColor' + | 'dark' + | 'ai' // symbolic token for AI gradient colors, this does not exist in the theme + | 'navigationPrimaryBaseColor' + | 'navigationPrimaryHoverColor' + | 'navigationPrimaryActiveColor' + | 'navigationPrimaryOnColorBaseColor' + | 'navigationPrimaryOnColorHoverColor' + | 'navigationPrimaryOnColorActiveColor' + | 'actionSecondaryBaseColor' + | 'actionSecondaryHoverColor' + | 'actionSecondaryActiveColor' + | 'actionSecondaryDisabledColor' + | 'actionStatusBaseColor' + | 'actionStatusHoverColor' + | 'actionStatusActiveColor' + | 'actionStatusDisabledColor' + // | 'actionAiSecondaryTopGradientBaseColor' internally used for AI gradient + // | 'actionAiSecondaryBottomGradientBaseColor' internally used for AI gradient + | 'actionAiBaseColor' + | 'actionAiHoverColor' + | 'actionAiActiveColor' + | 'actionAiDisabledColor' + | 'actionPrimaryBaseColor' + | 'actionPrimaryHoverColor' + | 'actionPrimaryActiveColor' + | 'actionPrimaryDisabledColor' + | 'actionPrimaryOnColorBaseColor' + | 'actionPrimaryOnColorHoverColor' + | 'actionPrimaryOnColorActiveColor' + | 'actionPrimaryOnColorDisabledColor' + | 'accentBlueColor' + | 'accentGreenColor' + | 'accentRedColor' + | 'accentOrangeColor' + | 'accentGreyColor' + | 'accentAshColor' + | 'accentPlumColor' + | 'accentVioletColor' + | 'accentStoneColor' + | 'accentSkyColor' + | 'accentHoneyColor' + | 'accentSeaColor' + | 'accentAutoraColor' + | 'actionTertiaryBaseColor' + | 'actionTertiaryHoverColor' + | 'actionTertiaryActiveColor' + | 'actionTertiaryDisabledColor' + | 'actionSuccessSecondaryBaseColor' + | 'actionSuccessSecondaryDisabledColor' + | 'actionDestructiveSecondaryBaseColor' + | 'actionDestructiveSecondaryDisabledColor' + | 'actionAiSecondaryDisabledColor' + | 'actionSecondaryOnColorBaseColor' + | 'actionSecondaryOnColorHoverColor' + | 'actionSecondaryOnColorActiveColor' + | 'actionSecondaryOnColorDisabledColor' + | 'actionSuccessSecondaryHoverColor' + | 'actionSuccessSecondaryActiveColor' + | 'actionDestructiveSecondaryHoverColor' + | 'actionDestructiveSecondaryActiveColor' type InstUIIconOwnProps = { /** - * Semantic size token or numeric pixels - */ - size?: IconSizeToken | number - /** - * Semantic stroke width token or numeric value + * Semantic size token (also determines stroke width automatically) */ - strokeWidth?: IconStrokeWidthToken | number | string + size?: IconSizeToken /** - * Icon theme color token or CSS color value + * Icon theme color token */ - color?: 'inherit' | IconColorToken | string + color?: 'inherit' | IconColorToken | LegacyColorTokens /** * Rotation angle in degrees */ @@ -94,17 +159,40 @@ type InstUIIconOwnProps = { } /** - * Full props: Lucide native + InstUI semantic + theme support. - * InstUI props override Lucide's size, color, strokeWidth, rotate. + * Full props: InstUI semantic + theme support + SVG attributes. + * OtherHTMLAttributes provides SVG props for backward compatibility. + * children, style, and className are explicitly omitted. */ type LucideIconWrapperProps = Omit< - LucideProps, - 'size' | 'color' | 'strokeWidth' | 'rotate' -> & InstUIIconOwnProps & { themeOverride?: ThemeOverrideValue - } & OtherHTMLAttributes + } & OtherHTMLAttributes, + 'children' | 'style' | 'className' +> -type LucideIconStyle = ComponentStyle<'lucideIcon'> +type LucideIconStyle = ComponentStyle<'lucideIcon'> & { + /** + * Computed numeric size for Lucide icon (in pixels) + */ + numericSize?: number + /** + * Computed numeric stroke width for Lucide icon + */ + numericStrokeWidth?: number | string + /** + * Resolved color from theme for Lucide icon + */ + resolvedColor?: string + /** + * Gradient colors for AI gradient (top and bottom) + */ + gradientColors?: { top: string; bottom: string } +} -export type { LucideIconWrapperProps, InstUIIconOwnProps, LucideIconStyle } +export type { + LucideIconWrapperProps, + InstUIIconOwnProps, + LucideIconStyle, + SVGIconSizeToken, + LegacyColorTokens +} diff --git a/packages/ui-icons-lucide/src/wrapLucideIcon/styles.ts b/packages/ui-icons-lucide/src/wrapLucideIcon/styles.ts index 7fc144bb9d..69e746d2c6 100644 --- a/packages/ui-icons-lucide/src/wrapLucideIcon/styles.ts +++ b/packages/ui-icons-lucide/src/wrapLucideIcon/styles.ts @@ -22,8 +22,9 @@ * SOFTWARE. */ +import { px } from '@instructure/ui-utils' import type { NewComponentTypes } from '@instructure/ui-themes' -import type { LucideIconWrapperProps, LucideIconStyle } from './props' +import { LucideIconWrapperProps, LucideIconStyle } from './props' type StyleParams = { size?: LucideIconWrapperProps['size'] @@ -34,28 +35,176 @@ type StyleParams = { themeOverride?: LucideIconWrapperProps['themeOverride'] } +/** + * Maps icon size tokens to theme property names + */ +const SIZE_TOKEN_MAP = { + xs: 'sizeXs', + sm: 'sizeSm', + md: 'sizeMd', + lg: 'sizeLg', + xl: 'sizeXl', + '2xl': 'size2xl' +} + +/** + * Maps size tokens to strokeWidth theme property names + */ +const STROKE_WIDTH_TOKEN_MAP = { + xs: 'strokeWidthXs', + sm: 'strokeWidthSm', + md: 'strokeWidthMd', + lg: 'strokeWidthLg', + xl: 'strokeWidthXl', + '2xl': 'strokeWidth2xl' +} + +/** + * Legacy SVGIcon size tokens (DEPRECATED - will be removed in future version) + */ +const LEGACY_SIZE_MAP = { + 'x-small': '1.125rem', + small: '2rem', + medium: '3rem', + large: '5rem', + 'x-large': '10rem' +} + +/** + * Legacy SVGIcon color tokens (DEPRECATED - will be removed in future version) + */ +const LEGACY_COLOR_MAP = { + primary: 'baseColor', + secondary: 'mutedColor', + 'primary-inverse': 'onColor', + 'secondary-inverse': 'onColor', + success: 'successColor', + error: 'errorColor', + alert: 'infoColor', + warning: 'warningColor', + brand: 'infoColor', + auto: 'inherit' +} + +/** + * Convert semantic size token to numeric pixels for Lucide + */ +const convertSemanticSize = ( + size: LucideIconWrapperProps['size'], + componentTheme: NewComponentTypes['Icon'] +) => { + if (!size) return undefined + + // Check legacy SVGIcon tokens first (DEPRECATED) + if (size in LEGACY_SIZE_MAP) { + console.warn( + `Icon size "${size}" is deprecated. Use semantic tokens (xs, sm, md, lg, xl, 2xl) instead.` + ) + return px(LEGACY_SIZE_MAP[size as keyof typeof LEGACY_SIZE_MAP]) + } + + const themeKey = SIZE_TOKEN_MAP[size as keyof typeof SIZE_TOKEN_MAP] + if (themeKey && themeKey in componentTheme) { + return px(componentTheme[themeKey as keyof NewComponentTypes['Icon']]) + } + + // Warn if unknown token is passed + console.warn( + `Icon size "${size}" is not a valid semantic token. Valid tokens are: xs, sm, md, lg, xl, 2xl.` + ) + return undefined +} + +/** + * Convert semantic size token to stroke width value for Lucide + * Derives stroke width from size using matching token + */ +const convertSizeToStrokeWidth = ( + size: LucideIconWrapperProps['size'], + componentTheme: NewComponentTypes['Icon'] +) => { + if (!size) return undefined + + // Look up stroke width token matching the size + const themeKey = + STROKE_WIDTH_TOKEN_MAP[size as keyof typeof STROKE_WIDTH_TOKEN_MAP] + if (themeKey && themeKey in componentTheme) { + return px(componentTheme[themeKey as keyof NewComponentTypes['Icon']]) + } + + return undefined +} + +/** + * Determine semantic color value from theme + */ +const determineColorValue = ( + color: LucideIconWrapperProps['color'], + componentTheme: NewComponentTypes['Icon'] +) => { + if (!color) { + return undefined + } + + if (color === 'inherit' || color === 'ai') { + return color + } + + // Check legacy SVGIcon color tokens (DEPRECATED) + if (color in LEGACY_COLOR_MAP) { + const mappedColor = LEGACY_COLOR_MAP[color as keyof typeof LEGACY_COLOR_MAP] + console.warn( + `Icon color "${color}" is deprecated. Use "${mappedColor}" instead.` + ) + return mappedColor + } + + if (color in componentTheme) { + return color + } + + // Warn if unknown token is passed + console.warn(`Icon color "${color}" is not a valid semantic token.`) + return undefined +} + const generateStyle = ( componentTheme: NewComponentTypes['Icon'], params: StyleParams ): LucideIconStyle => { - const { color, rotate = '0', bidirectional = true, inline = true } = params - - /** - * Determine color value from theme or custom CSS - */ - let colorStyle: { color: string } | undefined - - if (color) { - if (color === 'inherit') { - colorStyle = { color: 'inherit' } - } else if (color in componentTheme) { - // Direct theme property access + const { + size, + color, + rotate = '0', + bidirectional = true, + inline = true + } = params + + const numericSize = convertSemanticSize(size, componentTheme) + // Derive stroke width from size + const numericStrokeWidth = convertSizeToStrokeWidth(size, componentTheme) + const colorValue = determineColorValue(color, componentTheme) + + let colorStyle + let gradientColors: { top: string; bottom: string } | undefined + let resolvedColor: string | undefined + + if (colorValue) { + if (colorValue === 'inherit') { + resolvedColor = 'currentColor' + } else if (colorValue === 'ai') { + // Special handling for AI gradient color + gradientColors = { + top: componentTheme.actionAiSecondaryTopGradientBaseColor, + bottom: componentTheme.actionAiSecondaryBottomGradientBaseColor + } + } else if (colorValue in componentTheme) { + const themeColor = + componentTheme[colorValue as keyof typeof componentTheme] colorStyle = { - color: componentTheme[color as keyof typeof componentTheme] as string + color: themeColor } - } else { - // Custom CSS color (e.g., "#ff0000", "rgb(255, 0, 0)") - colorStyle = { color } + resolvedColor = themeColor } } @@ -85,7 +234,11 @@ const generateStyle = ( ...(bidirectional && { '[dir="rtl"] &': bidirectionalRotateVariants[rotate] }) - } + }, + numericSize, + numericStrokeWidth, + resolvedColor, + gradientColors } } diff --git a/packages/ui-react-utils/src/IconPropsProvider/IconPropsContext.ts b/packages/ui-react-utils/src/IconPropsProvider/IconPropsContext.ts new file mode 100644 index 0000000000..3735d21415 --- /dev/null +++ b/packages/ui-react-utils/src/IconPropsProvider/IconPropsContext.ts @@ -0,0 +1,30 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React from 'react' +import type { IconPropsContextValue } from './IconPropsProvider' + +const IconPropsContext = React.createContext({}) + +export { IconPropsContext } diff --git a/packages/ui-react-utils/src/IconPropsProvider/IconPropsProvider.tsx b/packages/ui-react-utils/src/IconPropsProvider/IconPropsProvider.tsx new file mode 100644 index 0000000000..77edf44134 --- /dev/null +++ b/packages/ui-react-utils/src/IconPropsProvider/IconPropsProvider.tsx @@ -0,0 +1,49 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { IconPropsContext } from './IconPropsContext' + +type IconPropsContextValue = { + size?: string | number + color?: string +} + +type IconPropsProviderProps = React.PropsWithChildren + +const IconPropsProvider: React.FC = ({ + children, + size, + color +}) => { + const value = { size, color } + + return ( + + {children} + + ) +} + +export { IconPropsProvider } +export type { IconPropsContextValue } diff --git a/packages/ui-react-utils/src/IconPropsProvider/index.ts b/packages/ui-react-utils/src/IconPropsProvider/index.ts new file mode 100644 index 0000000000..7449089386 --- /dev/null +++ b/packages/ui-react-utils/src/IconPropsProvider/index.ts @@ -0,0 +1,28 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +export { IconPropsProvider } from './IconPropsProvider' +export { IconPropsContext } from './IconPropsContext' +export { useIconProps } from './useIconProps' +export type { IconPropsContextValue } from './IconPropsProvider' diff --git a/packages/ui-react-utils/src/IconPropsProvider/useIconProps.tsx b/packages/ui-react-utils/src/IconPropsProvider/useIconProps.tsx new file mode 100644 index 0000000000..6e362752bf --- /dev/null +++ b/packages/ui-react-utils/src/IconPropsProvider/useIconProps.tsx @@ -0,0 +1,32 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { useContext } from 'react' +import { IconPropsContext } from './IconPropsContext' + +function useIconProps() { + return useContext(IconPropsContext) +} + +export { useIconProps } diff --git a/packages/ui-react-utils/src/__tests__/IconPropsProvider.test.tsx b/packages/ui-react-utils/src/__tests__/IconPropsProvider.test.tsx new file mode 100644 index 0000000000..04172226dc --- /dev/null +++ b/packages/ui-react-utils/src/__tests__/IconPropsProvider.test.tsx @@ -0,0 +1,161 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { render, screen } from '@testing-library/react' +import '@testing-library/jest-dom' + +import { IconPropsProvider, useIconProps } from '../IconPropsProvider' + +// Test component that exposes context values +const TestComponentWithHook = () => { + const iconProps = useIconProps() + return ( +
+ + {iconProps?.size?.toString() || 'undefined'} + + {iconProps?.color || 'undefined'} +
+ ) +} + +// Mock icon component that uses context +const MockIconComponent = ({ testId = 'mock-icon' }: { testId?: string }) => { + const iconProps = useIconProps() + return ( +
+ Icon +
+ ) +} + +// Mock icon that accepts direct props and merges with context +const MockIconWithProps = ({ + size, + color, + testId = 'mock-icon-with-props' +}: { + size?: string | number + color?: string + testId?: string +}) => { + const contextProps = useIconProps() + const finalSize = size ?? contextProps?.size + const finalColor = color ?? contextProps?.color + + return ( +
+ Icon +
+ ) +} + +describe('IconPropsProvider', () => { + describe('useIconProps hook', () => { + it('should return context values when inside provider', () => { + render( + + + + ) + + expect(screen.getByTestId('size')).toHaveTextContent('lg') + expect(screen.getByTestId('color')).toHaveTextContent('baseColor') + }) + + it('should return empty object when outside provider', () => { + render() + + expect(screen.getByTestId('size')).toHaveTextContent('undefined') + expect(screen.getByTestId('color')).toHaveTextContent('undefined') + }) + + it('should return numeric size values', () => { + render( + + + + ) + + expect(screen.getByTestId('size')).toHaveTextContent('24') + expect(screen.getByTestId('color')).toHaveTextContent('accentRedColor') + }) + }) + + describe('Icon components receive props from context', () => { + it('should pass context values to icon component', () => { + render( + + + + ) + + const icon = screen.getByTestId('mock-icon') + expect(icon).toHaveAttribute('data-size', 'md') + expect(icon).toHaveAttribute('data-color', 'baseColor') + }) + + it('should work without IconPropsProvider', () => { + render() + + const icon = screen.getByTestId('mock-icon') + expect(icon).toHaveAttribute('data-size', 'none') + expect(icon).toHaveAttribute('data-color', 'none') + }) + }) + + describe('Direct props override context props', () => { + it('should allow direct props to override context', () => { + render( + + + + ) + + const icon = screen.getByTestId('mock-icon-with-props') + expect(icon).toHaveAttribute('data-size', '16') + expect(icon).toHaveAttribute('data-color', 'accentRedColor') + }) + + it('should use context when no direct props provided', () => { + render( + + + + ) + + const icon = screen.getByTestId('mock-icon-with-props') + expect(icon).toHaveAttribute('data-size', '24') + expect(icon).toHaveAttribute('data-color', 'baseColor') + }) + }) +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 519e25dc51..5a0215ff01 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1016,9 +1016,9 @@ importers: '@instructure/shared-types': specifier: workspace:* version: link:../shared-types - '@instructure/ui-icons': + '@instructure/ui-icons-lucide': specifier: workspace:* - version: link:../ui-icons + version: link:../ui-icons-lucide '@instructure/ui-react-utils': specifier: workspace:* version: link:../ui-react-utils @@ -2447,8 +2447,8 @@ importers: specifier: workspace:* version: link:../ui-utils lucide-react: - specifier: ^0.460.0 - version: 0.460.0(react@18.3.1) + specifier: ^0.559.0 + version: 0.559.0(react@18.3.1) devDependencies: '@instructure/ui-babel-preset': specifier: workspace:* @@ -10528,8 +10528,8 @@ packages: lru-queue@0.1.0: resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} - lucide-react@0.460.0: - resolution: {integrity: sha512-BVtq/DykVeIvRTJvRAgCsOwaGL8Un3Bxh8MbDxMhEWlZay3T4IpEKDEpwt5KZ0KJMHzgm6jrltxlT5eXOWXDHg==} + lucide-react@0.559.0: + resolution: {integrity: sha512-3ymrkBPXWk3U2bwUDg6TdA6hP5iGDMgPEAMLhchEgTQmA+g0Zk24tOtKtXMx35w1PizTmsBC3RhP88QYm+7mHQ==} peerDependencies: react: 18.3.1 @@ -19716,7 +19716,7 @@ snapshots: dependencies: es5-ext: 0.10.64 - lucide-react@0.460.0(react@18.3.1): + lucide-react@0.559.0(react@18.3.1): dependencies: react: 18.3.1