diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 519810d..856a5d5 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -12,9 +12,6 @@ permissions: jobs: build: - # allow failure publishing to npm for now - # TODO: remove this once we have a token - continue-on-error: ${{ matrix.registry.url == 'https://registry.npmjs.org' }} strategy: matrix: registry: @@ -39,14 +36,26 @@ jobs: node-version-file: '.nvmrc' cache: pnpm registry-url: ${{ matrix.registry.url }} - scope: "@invoke-ai" + scope: '@invoke-ai' + + # TODO: remove when https://github.com/pnpm/pnpm/issues/7579 is resolved + - name: Reinstall @invoke-ai packages + shell: bash + run: | + VERSION_ESLINT=$(node -p "require('./package.json').devDependencies['@invoke-ai/eslint-config-react']") + VERSION_PRETTIER=$(node -p "require('./package.json').devDependencies['@invoke-ai/prettier-config-react']") + + pnpm uninstall @invoke-ai/eslint-config-react @invoke-ai/prettier-config-react + pnpm install --ignore-scripts -D @invoke-ai/eslint-config-react@$VERSION_ESLINT -D @invoke-ai/prettier-config-react@$VERSION_PRETTIER + env: + NODE_AUTH_TOKEN: ${{ secrets[matrix.registry.token_secret] }} - name: Install dependencies run: pnpm install --frozen-lockfile --ignore-scripts env: NODE_AUTH_TOKEN: ${{ secrets[matrix.registry.token_secret] }} - - name: Version bump + - name: Version bump (prepatch) # only if manual workflow dispatch and not on a tag if: github.event_name == 'workflow_dispatch' && !startsWith(github.ref, 'refs/tags/') run: npm version prepatch --preid=$(git rev-parse --short HEAD) --no-git-tag-version diff --git a/.gitignore b/.gitignore index a547bf3..017d3be 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ dist-ssr *.njsproj *.sln *.sw? + +stats.html diff --git a/lib/components/context-menu/context-menu.tsx b/lib/components/context-menu/context-menu.tsx index 06717f4..453ea59 100644 --- a/lib/components/context-menu/context-menu.tsx +++ b/lib/components/context-menu/context-menu.tsx @@ -33,7 +33,9 @@ export const ContextMenu = typedMemo((props onClose(); return; } - if (targetRef.current?.contains(e.target as HTMLElement) || e.target === targetRef.current) { + // `contains()` requires the arg to be Node. Technically it can be any EventTarget, but it won't cause an error. + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */ + if (targetRef.current?.contains(e.target as Node) || e.target === targetRef.current) { // clear pending delayed open window.clearTimeout(timeoutRef.current); e.preventDefault(); diff --git a/lib/components/custom-select/custom-select.tsx b/lib/components/custom-select/custom-select.tsx index b34d5ba..49d801b 100644 --- a/lib/components/custom-select/custom-select.tsx +++ b/lib/components/custom-select/custom-select.tsx @@ -89,7 +89,7 @@ export const CustomSelect = (props: CustomSelectProps) => { const value = useMemo(() => (selectedItem ? [selectedItem.value] : []), [selectedItem]); const groupedItems = useMemo(() => { - const _groupedItems = items.reduce(groupedItemsReducer, [] as ItemGroup[]); + const _groupedItems = items.reduce(groupedItemsReducer, []); _groupedItems.sort(groupSortFunc); return _groupedItems; }, [groupSortFunc, items]); diff --git a/lib/components/slider/range-slider-mark.tsx b/lib/components/slider/range-slider-mark.tsx index d878190..0c12a2f 100644 --- a/lib/components/slider/range-slider-mark.tsx +++ b/lib/components/slider/range-slider-mark.tsx @@ -3,7 +3,7 @@ import { motion } from 'framer-motion'; import { typedMemo } from '../../util'; import type { SliderMarkProps } from './slider-mark'; -import { sliderMarkAnimationConstants } from './slider-mark'; +import { sliderMarkStyles } from './slider-mark-styles'; export type RangeSliderMarkProps = SliderMarkProps; @@ -12,12 +12,12 @@ export const RangeSliderMark = typedMemo(({ value, label, index, total }: RangeS return ( {label} @@ -28,12 +28,12 @@ export const RangeSliderMark = typedMemo(({ value, label, index, total }: RangeS return ( {label} @@ -43,9 +43,9 @@ export const RangeSliderMark = typedMemo(({ value, label, index, total }: RangeS return ( diff --git a/lib/components/slider/slider-mark-styles.ts b/lib/components/slider/slider-mark-styles.ts new file mode 100644 index 0000000..7412ac4 --- /dev/null +++ b/lib/components/slider/slider-mark-styles.ts @@ -0,0 +1,50 @@ +import type { SystemStyleObject } from '@chakra-ui/styled-system'; +import type { MotionProps } from 'framer-motion'; + +const initialFirstLast: MotionProps['initial'] = { opacity: 0, y: 10 }; +const initialOther = { ...initialFirstLast, x: '-50%' }; + +const animateFirstLast: MotionProps['animate'] = { + opacity: 1, + y: 0, + transition: { duration: 0.2, ease: 'easeOut' }, +}; +const animateOther: MotionProps['animate'] = { ...animateFirstLast, x: '-50%' }; + +const exitFirstLast: MotionProps['exit'] = { + opacity: 0, + y: 10, + transition: { duration: 0.2, ease: 'anticipate' }, +}; +const exitOther: MotionProps['exit'] = { ...exitFirstLast, x: '-50%' }; + +const firstMarkStyle: SystemStyleObject = { + insetInlineStart: '0 !important', + insetInlineEnd: 'unset !important', +}; +const lastMarkStyle: SystemStyleObject = { + insetInlineStart: 'unset !important', + insetInlineEnd: '0 !important', +}; + +type SliderMarkAnimationOptions = { + initialFirstLast: MotionProps['initial']; + initialOther: MotionProps['initial']; + exitFirstLast: MotionProps['exit']; + exitOther: MotionProps['exit']; + animateFirstLast: MotionProps['animate']; + animateOther: MotionProps['animate']; + firstMarkStyle: SystemStyleObject; + lastMarkStyle: SystemStyleObject; +}; + +export const sliderMarkStyles: SliderMarkAnimationOptions = { + initialFirstLast, + initialOther, + exitFirstLast, + exitOther, + animateFirstLast, + animateOther, + firstMarkStyle, + lastMarkStyle, +} as const; diff --git a/lib/components/slider/slider-mark.tsx b/lib/components/slider/slider-mark.tsx index 4a2dbf8..f1d365b 100644 --- a/lib/components/slider/slider-mark.tsx +++ b/lib/components/slider/slider-mark.tsx @@ -1,57 +1,8 @@ import { SliderMark as ChakraSliderMark } from '@chakra-ui/react'; -import type { SystemStyleObject } from '@chakra-ui/styled-system'; -import type { MotionProps } from 'framer-motion'; import { motion } from 'framer-motion'; import { typedMemo } from '../../util'; - -const initialFirstLast: MotionProps['initial'] = { opacity: 0, y: 10 }; -const initialOther = { ...initialFirstLast, x: '-50%' }; - -const animateFirstLast: MotionProps['animate'] = { - opacity: 1, - y: 0, - transition: { duration: 0.2, ease: 'easeOut' }, -}; -const animateOther: MotionProps['animate'] = { ...animateFirstLast, x: '-50%' }; - -const exitFirstLast: MotionProps['exit'] = { - opacity: 0, - y: 10, - transition: { duration: 0.2, ease: 'anticipate' }, -}; -const exitOther: MotionProps['exit'] = { ...exitFirstLast, x: '-50%' }; - -const firstMarkStyle: SystemStyleObject = { - insetInlineStart: '0 !important', - insetInlineEnd: 'unset !important', -}; -const lastMarkStyle: SystemStyleObject = { - insetInlineStart: 'unset !important', - insetInlineEnd: '0 !important', -}; - -type SliderMarkAnimationOptions = { - initialFirstLast: MotionProps['initial']; - initialOther: MotionProps['initial']; - exitFirstLast: MotionProps['exit']; - exitOther: MotionProps['exit']; - animateFirstLast: MotionProps['animate']; - animateOther: MotionProps['animate']; - firstMarkStyle: SystemStyleObject; - lastMarkStyle: SystemStyleObject; -}; - -export const sliderMarkAnimationConstants: SliderMarkAnimationOptions = { - initialFirstLast, - initialOther, - exitFirstLast, - exitOther, - animateFirstLast, - animateOther, - firstMarkStyle, - lastMarkStyle, -} as const; +import { sliderMarkStyles } from './slider-mark-styles'; export type SliderMarkProps = { value: number; @@ -65,12 +16,12 @@ export const SliderMark = typedMemo(({ value, label, index, total }: SliderMarkP return ( {label} @@ -81,12 +32,12 @@ export const SliderMark = typedMemo(({ value, label, index, total }: SliderMarkP return ( {label} @@ -96,9 +47,9 @@ export const SliderMark = typedMemo(({ value, label, index, total }: SliderMarkP return ( diff --git a/lib/theme/space.ts b/lib/theme/space.ts index 92481c9..489989a 100644 --- a/lib/theme/space.ts +++ b/lib/theme/space.ts @@ -4,12 +4,12 @@ const getSpaceValues = (fractionOfDefault = 0.75) => { 80, 96, ]; - const spaceObject = spaceKeys.reduce( + const spaceObject = spaceKeys.reduce>( (acc, val) => { acc[val] = `${val * (0.25 * fractionOfDefault)}rem`; return acc; }, - { px: '1px' } as Record + { px: '1px' } ); return spaceObject; diff --git a/lib/theme/util/generateColorPalette.ts b/lib/theme/util/generateColorPalette.ts index 8dded92..92b4989 100644 --- a/lib/theme/util/generateColorPalette.ts +++ b/lib/theme/util/generateColorPalette.ts @@ -15,14 +15,21 @@ export function generateColorPalette(H: string | number, S: string | number, alp const lightnessSteps = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 59, 64, 68, 73, 77, 82, 86, 95, 100]; const p = colorSteps.reduce((palette, step, index) => { + // We know this is a number. + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */ const A = alpha ? (lightnessSteps[index] as number) / 100 : 1; // Lightness should be 50% for alpha colors const L = alpha ? 50 : lightnessSteps[colorSteps.length - 1 - index]; - palette[step as keyof typeof palette] = `hsl(${H} ${S}% ${L}% / ${A})`; + // We know this is a key of PaletteSteps. + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */ + palette[step as keyof PaletteSteps] = `hsl(${H} ${S}% ${L}% / ${A})`; return palette; + + // We know this will eventually be a valid PaletteSteps object. + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */ }, {} as PaletteSteps); return p; diff --git a/package.json b/package.json index 2ac1831..b83ef26 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,6 @@ "type": "git", "url": "git+https://github.com/invoke-ai/ui-library.git" }, - "publishConfig": { - "access": "public", - "registry": "https://npm.pkg.github.com" - }, "author": "Invoke", "license": "Apache-2.0", "bugs": { @@ -62,8 +58,8 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "@invoke-ai/eslint-config-react": "^0.0.8", - "@invoke-ai/prettier-config-react": "^0.0.3", + "@invoke-ai/eslint-config-react": "^0.0.11", + "@invoke-ai/prettier-config-react": "^0.0.6", "@storybook/addon-essentials": "^7.6.10", "@storybook/addon-interactions": "^7.6.10", "@storybook/addon-links": "^7.6.10", @@ -79,6 +75,7 @@ "@vitejs/plugin-react": "^4.2.1", "eslint": "^8.56.0", "prettier": "^3.2.4", + "rollup-plugin-visualizer": "^5.12.0", "storybook": "^7.6.10", "typescript": "^5.3.3", "vite": "^5.0.12", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aec6042..8374271 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -77,11 +77,11 @@ dependencies: devDependencies: '@invoke-ai/eslint-config-react': - specifier: ^0.0.8 - version: 0.0.8(@typescript-eslint/eslint-plugin@6.19.1)(@typescript-eslint/parser@6.19.1)(eslint-config-prettier@9.1.0)(eslint-plugin-i18next@6.0.3)(eslint-plugin-import@2.29.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react-refresh@0.4.5)(eslint-plugin-react@7.33.2)(eslint-plugin-simple-import-sort@10.0.0)(eslint-plugin-storybook@0.6.15)(eslint-plugin-unused-imports@3.0.0)(eslint@8.56.0) + specifier: ^0.0.11 + version: 0.0.11(@typescript-eslint/eslint-plugin@6.19.1)(@typescript-eslint/parser@6.19.1)(eslint-config-prettier@9.1.0)(eslint-plugin-i18next@6.0.3)(eslint-plugin-import@2.29.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react-refresh@0.4.5)(eslint-plugin-react@7.33.2)(eslint-plugin-simple-import-sort@10.0.0)(eslint-plugin-storybook@0.6.15)(eslint-plugin-unused-imports@3.0.0)(eslint@8.56.0) '@invoke-ai/prettier-config-react': - specifier: ^0.0.3 - version: 0.0.3(prettier@3.2.4) + specifier: ^0.0.6 + version: 0.0.6(prettier@3.2.4) '@storybook/addon-essentials': specifier: ^7.6.10 version: 7.6.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) @@ -127,6 +127,9 @@ devDependencies: prettier: specifier: ^3.2.4 version: 3.2.4 + rollup-plugin-visualizer: + specifier: ^5.12.0 + version: 5.12.0 storybook: specifier: ^7.6.10 version: 7.6.10 @@ -3281,8 +3284,8 @@ packages: '@swc/helpers': 0.5.3 dev: false - /@invoke-ai/eslint-config-react@0.0.8(@typescript-eslint/eslint-plugin@6.19.1)(@typescript-eslint/parser@6.19.1)(eslint-config-prettier@9.1.0)(eslint-plugin-i18next@6.0.3)(eslint-plugin-import@2.29.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react-refresh@0.4.5)(eslint-plugin-react@7.33.2)(eslint-plugin-simple-import-sort@10.0.0)(eslint-plugin-storybook@0.6.15)(eslint-plugin-unused-imports@3.0.0)(eslint@8.56.0): - resolution: {integrity: sha512-IxaMSYgwsZV/LpaG+o1CF96mM+gbTj3JWKQbEgHCs5QLZ/eWJOjSmQ1Dz7OjWr52A5CAcbMJmc1uHowK5tT6WA==, tarball: https://npm.pkg.github.com/download/@invoke-ai/eslint-config-react/0.0.8/ee3d6efbcbd26ce5cd4fbd13c9a440fd216bb09d} + /@invoke-ai/eslint-config-react@0.0.11(@typescript-eslint/eslint-plugin@6.19.1)(@typescript-eslint/parser@6.19.1)(eslint-config-prettier@9.1.0)(eslint-plugin-i18next@6.0.3)(eslint-plugin-import@2.29.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react-refresh@0.4.5)(eslint-plugin-react@7.33.2)(eslint-plugin-simple-import-sort@10.0.0)(eslint-plugin-storybook@0.6.15)(eslint-plugin-unused-imports@3.0.0)(eslint@8.56.0): + resolution: {integrity: sha512-To3m1qd1XMOkBYAenVT6Zjb1iTvSwetoJZrCITD4DHAtYu/3srhYVykJrNEjslCvz7AGDRtDDCczcQMOIwUJOQ==} peerDependencies: '@typescript-eslint/eslint-plugin': ^6.19.0 '@typescript-eslint/parser': ^6.19.0 @@ -3311,8 +3314,8 @@ packages: eslint-plugin-unused-imports: 3.0.0(@typescript-eslint/eslint-plugin@6.19.1)(eslint@8.56.0) dev: true - /@invoke-ai/prettier-config-react@0.0.3(prettier@3.2.4): - resolution: {integrity: sha512-hnjS1plindk/AoSOpBVznWFmdfgjBgbXVuRDZELhxr6y2tF6ADZPst29vwqoNbJUS90b3Yojlz7hVSlJCTJc+w==, tarball: https://npm.pkg.github.com/download/@invoke-ai/prettier-config-react/0.0.3/d0244466e95bbea78a0b9de95256c60b48fb8939} + /@invoke-ai/prettier-config-react@0.0.6(prettier@3.2.4): + resolution: {integrity: sha512-qHE6GAw/Aka/8TLTN9U1U+8pxjaFe5irDv/uSgzqmrBR1rGiVyMp19pEficWRRt+03zYdquiiDjTmoabWQxY0Q==} peerDependencies: prettier: ^3.2.4 dependencies: @@ -6902,6 +6905,15 @@ packages: '@colors/colors': 1.5.0 dev: true + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + /clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} engines: {node: '>=6'} @@ -8273,6 +8285,11 @@ packages: engines: {node: '>=6.9.0'} dev: true + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + /get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} dev: true @@ -10529,6 +10546,11 @@ packages: unist-util-visit: 2.0.3 dev: true + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + /requireindex@1.1.0: resolution: {integrity: sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg==} engines: {node: '>=0.10.5'} @@ -10606,6 +10628,22 @@ packages: glob: 7.2.3 dev: true + /rollup-plugin-visualizer@5.12.0: + resolution: {integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rollup: + optional: true + dependencies: + open: 8.4.2 + picomatch: 2.3.1 + source-map: 0.7.4 + yargs: 17.7.2 + dev: true + /rollup@3.29.4: resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} @@ -10821,6 +10859,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: true + /space-separated-tokens@1.1.5: resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} dev: true @@ -11771,6 +11814,11 @@ packages: engines: {node: '>=0.4'} dev: true + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} dev: true @@ -11784,6 +11832,24 @@ packages: engines: {node: '>= 6'} dev: false + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + /yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} dependencies: diff --git a/vite.config.ts b/vite.config.ts index 03bce3c..ce6efcc 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,6 @@ import react from '@vitejs/plugin-react'; import { resolve } from 'path'; +import { visualizer } from 'rollup-plugin-visualizer'; import { defineConfig } from 'vite'; import dts from 'vite-plugin-dts'; @@ -17,6 +18,7 @@ export default defineConfig({ 'lib/theme/layers.ts', ], }), + visualizer(), ], build: { lib: { @@ -24,7 +26,7 @@ export default defineConfig({ formats: ['es'], }, rollupOptions: { - external: ['react', 'react/jsx-runtime'], + external: ['react', 'react/jsx-runtime', 'react-dom'], output: { assetFileNames: 'assets/[name][extname]', entryFileNames: '[name].js',