From 299f7741ead460e1eb65a7c112060af21a324f0e Mon Sep 17 00:00:00 2001 From: witt Date: Fri, 13 Aug 2021 17:31:45 +0800 Subject: [PATCH] chore: release v2.2.0 (#602) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(slider): add option to hide slider value (#494) * feat(slider): hideValue prop added * test(slider): test added for hideValue prop docs(slider): add hideValue prop docs(slider): add hideValue prop for cn docs feat(slider): ensure the dot stays round when no content test(slider): update snapshots * feat(loading): apply width & height props (#500) * feat(loading): apply width & height props * test(loading): test case added & updating snapshots * fix(loading): add a string type for size prop test(loading): update test case & snapshots * feat(loading): support custom the ratio of spaces * docs(loading): append size and spaceRatio test(loading): update snapshots Co-authored-by: unix * chore(deps): update styled-jsx to ^3.3.1 (#520) * chore(deps): update styled-jsx to ^3.3.1 update styled-jsx to ^3.3.1 to allow compatiblity with react@^17 * fix(modules): fix 695-issue to compatible with React 17 * docs: fix module error caused by styled-jsx update Co-authored-by: unix * chore: release v2.2.0-rc.0 * fix(modal): disable backdrop even if actions missing (#532) * fix: upgrade to be compatible with React-17's event system (#533) * feat: useKeyboard hooks (#541) * feat(keyboard): create keyboard hooks * feat(usekeyboard): redesign event handler to match keyboard events from browser \ * test(usekeyboard): add testcase * docs(usekeyboard): create new hooks document * chore: release v2.2.0-rc.1 * feat(auto-complete): add forwardRef for input element (#542) * feat(auto-complete): add forwardRef for input element * test(auto-complete): add testcase to ensure ref is available * docs(auto-complete): append props for ref * chore: release v2.2.0-rc.2 * fix(auto-complete): fix size of loading icon (#546) * chore: release v2.2.0-rc.3 * fix(auto-complete): hide shadow when no content (#547) * chore: release v2.2.0-rc.4 * feat: add status prop in checkbox, radio, select, slider and toggle (#530) * feat: added status prop to set color by states test: check status success, warning and error * docs: added playground example and API reference fix: replaced ´_´ as it's not recommended to use fix: removed redundant return refactor: renamed prop from status to type test: update test with the renamed prop * docs: update prop references from status to type fix: status prop not updated to type fix: missing return * fix(select): set icons and hover state to follow the theme * test(slider): update snapshots * chore: always use relative paths when import types Co-authored-by: unix * feat(auto-complete): add props for popup container (#558) * feat(auto-complete): add props for popup container * docs(auto-complete): add attribute for popup container * chore: release v2.2.0-rc.5 * fix: fix path error under esm * chore: release v2.2.0-rc.6 * feat(scaleable): add scaleable props to each component (#531) * feat(scaleable): add scaleable props to each component * chore(scaleable): update the exported type * feat: apply scaleable to components chore: remove with-default test: improve testcase for scaleable chore: resolve test warning ci: upgrade nodejs to latest lts docs: fix type error in document site * docs: update documents to be compatible with scaleable chore: fix build errors * chore: remove all size-related attributes docs: improve guide document * docs: add scaleable documentation test: update snapshots chore: remove unused * feat: add scaleable to grid components * docs: improve docs * test: update snapshots * fix(grid): fix basic component props * feat: export all types related to components (#562) * feat: export all types related to components fix(tooltip): fix the vertical offset of the arrow * refactor: optimize events of all popup related components * test: append testcases for popup base component * test: add testcase for visible events * test: update snapshots * fix(bundle): fix modules missing in yarn berry (#563) * chore: add peer dependencies * fix(bundle): fix modules missing in yarn berry * chore: upgrade configs for jest 27 * chore(examples): upgrade next examples for scaleable (#564) * chore: release v2.2.0-rc.7 * feat(rating): a new component rating indicator (#543) * chore(deps): bump lodash from 4.17.20 to 4.17.21 (#537) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * (feature) rating state working and islocked working * (feature) custom emojis for the ratings added * refactor(rating): migrate component to scaleable * feat(rating): use inline icon component test(rating): update testcase * docs(rating): add document for zh-cn Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: unix * refactor(table): redesign interfaces to improve the experience in TypeScript (#569) * refactor(table): redesign interfaces to improve the experience in TypeScript * docs: upgrade to new type exports * style: fix lint warnings * docs: fix sidebar text-transform (#570) * docs: improve the copywriting content of the document (#571) * docs: export individual style types for each component * docs: improve the copywriting content of the document * docs: optimize the document site experience on mobile devices * chore: release v2.2.0-rc.8 * feat(modal): responds to keyboard events when modal is displayed (#574) * docs: redesign mobile navigation (#576) * docs: redesign mobile navigation * docs: fix subheading active color * fix(avatar): fix margin on first child (#578) Co-authored-by: witt * feat(select): imporve the focus events to export simulated ref (#579) * feat(select): imporve the focus events to export simulated ref * test: improve testcase and fix warnings * docs(select): add label and divider to props docs * fix: rename hymlType to htmlType (#599) * feat(drawer): create component (#575) * feat(drawer): create component * feat(drawer): refinement of drawer component * test: update tool chain for jest * test: simplify events case for jest * docs(drawer): add playground * docs(drawer): add api docs * docs: add home page (#573) * docs: add home page * docs(homepage): apply suggestions from code review * docs(homepage): make cards clickable Co-authored-by: witt * test: update snapshots for scaleable * chore: update lock file * chore: upgrade styled-jsx * test: update snapshots for styled-jsx Co-authored-by: Deepankar Co-authored-by: Deepankar Co-authored-by: Florian Levis Co-authored-by: gepd Co-authored-by: Nils J Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ofek Ashery Co-authored-by: Sanna Jammeh <50969683+sannajammeh@users.noreply.github.com> --- .circleci/config.yml | 4 +- .jest.config.js | 8 +- .../__snapshots__/index.test.tsx.snap | 13 +- .../__snapshots__/search.test.tsx.snap | 396 +- .../auto-complete/__tests__/index.test.tsx | 15 +- .../auto-complete/auto-complete-context.ts | 3 - .../auto-complete/auto-complete-dropdown.tsx | 30 +- .../auto-complete/auto-complete-empty.tsx | 12 +- .../auto-complete/auto-complete-item.tsx | 56 +- .../auto-complete/auto-complete-searching.tsx | 26 +- components/auto-complete/auto-complete.tsx | 347 +- components/auto-complete/index.ts | 22 +- .../__snapshots__/index.test.tsx.snap | 621 +- components/avatar/__tests__/index.test.tsx | 9 +- components/avatar/avatar-group.tsx | 26 +- components/avatar/avatar.tsx | 63 +- components/avatar/index.ts | 10 +- .../__snapshots__/anchor.test.tsx.snap | 45 +- .../__snapshots__/index.test.tsx.snap | 636 +- components/badge/__tests__/index.test.tsx | 8 +- components/badge/badge-anchor.tsx | 13 +- components/badge/badge.tsx | 62 +- components/badge/index.ts | 9 +- .../__snapshots__/breadcrumbs.test.tsx.snap | 21 +- components/breadcrumbs/breadcrumbs-item.tsx | 20 +- .../breadcrumbs/breadcrumbs-separator.tsx | 22 +- components/breadcrumbs/breadcrumbs.tsx | 47 +- components/breadcrumbs/index.ts | 13 +- .../__snapshots__/index.test.tsx.snap | 1476 ++-- .../button-dropdown/__tests__/index.test.tsx | 8 +- .../button-dropdown-context.ts | 4 +- .../button-dropdown/button-dropdown-item.tsx | 29 +- .../button-dropdown/button-dropdown.tsx | 62 +- components/button-dropdown/icon.tsx | 5 +- components/button-dropdown/index.ts | 12 +- .../__snapshots__/index.test.tsx.snap | 105 +- .../button-group/__tests__/index.test.tsx | 2 +- .../button-group/button-group-context.ts | 3 +- components/button-group/button-group.tsx | 45 +- components/button-group/index.ts | 2 + .../__snapshots__/icon.test.tsx.snap | 63 +- .../__snapshots__/index.test.tsx.snap | 6 +- components/button/__tests__/icon.test.tsx | 4 +- components/button/__tests__/index.test.tsx | 12 - components/button/button-icon.tsx | 15 +- components/button/button-loading.tsx | 3 +- components/button/button.drip.tsx | 16 +- components/button/button.tsx | 75 +- components/button/index.ts | 2 + components/button/styles.ts | 69 +- components/button/utils.tsx | 20 +- .../__snapshots__/index.test.tsx.snap | 280 +- components/capacity/capacity.tsx | 22 +- components/capacity/index.ts | 1 + .../__snapshots__/footer.test.tsx.snap | 33 +- .../__snapshots__/index.test.tsx.snap | 1540 ++-- components/card/card-content.tsx | 28 +- components/card/card-footer.tsx | 25 +- components/card/card.tsx | 35 +- components/card/index.ts | 20 +- .../__snapshots__/group.test.tsx.snap | 458 +- .../__snapshots__/index.test.tsx.snap | 232 +- components/checkbox/__tests__/group.test.tsx | 21 - components/checkbox/__tests__/index.test.tsx | 11 +- components/checkbox/checkbox-group.tsx | 43 +- components/checkbox/checkbox.icon.tsx | 26 +- components/checkbox/checkbox.tsx | 62 +- components/checkbox/index.ts | 18 +- components/checkbox/styles.ts | 38 + .../__snapshots__/index.test.tsx.snap | 205 +- components/code/code.tsx | 25 +- components/code/index.ts | 3 +- .../__snapshots__/index.test.tsx.snap | 80 +- components/col/__tests__/index.test.tsx | 2 +- components/col/col.tsx | 11 +- components/col/index.ts | 3 +- .../__snapshots__/group.test.tsx.snap | 866 ++- .../__snapshots__/index.test.tsx.snap | 1732 ++--- components/collapse/collapse-group.tsx | 26 +- components/collapse/collapse-icon.tsx | 4 +- components/collapse/collapse.tsx | 39 +- components/collapse/index.ts | 9 +- .../__snapshots__/baseline.test.tsx.snap | 228 +- components/css-baseline/css-baseline.tsx | 34 +- components/description/description.tsx | 37 +- components/description/index.ts | 3 +- .../__snapshots__/index.test.tsx.snap | 242 +- components/display/display.tsx | 33 +- components/display/index.ts | 3 +- .../__snapshots__/index.test.tsx.snap | 806 +- components/divider/__tests__/index.test.tsx | 12 +- components/divider/divider.tsx | 42 +- components/divider/index.ts | 2 + .../__snapshots__/index.test.tsx.snap | 896 ++- components/dot/dot.tsx | 42 +- components/dot/index.ts | 3 +- .../__snapshots__/index.test.tsx.snap | 905 +++ components/drawer/__tests__/index.test.tsx | 151 + .../drawer/__tests__/use-modal.test.tsx | 37 + components/drawer/drawer-wrapper.tsx | 160 + components/drawer/drawer.tsx | 91 + components/drawer/helper.ts | 36 + components/drawer/index.ts | 21 + .../__snapshots__/index.test.tsx.snap | 3477 +++------ components/fieldset/__tests__/index.test.tsx | 12 +- components/fieldset/fieldset-content.tsx | 27 +- .../fieldset/fieldset-footer-actions.tsx | 37 - .../fieldset/fieldset-footer-status.tsx | 44 - components/fieldset/fieldset-footer.tsx | 34 +- components/fieldset/fieldset-group.tsx | 33 +- components/fieldset/fieldset-subtitle.tsx | 22 +- components/fieldset/fieldset-title.tsx | 23 +- components/fieldset/fieldset.tsx | 34 +- components/fieldset/index.ts | 32 +- components/geist-provider/geist-provider.tsx | 4 +- components/geist-provider/index.ts | 1 + .../__snapshots__/index.test.tsx.snap | 40 + components/grid/basic-item.tsx | 64 +- components/grid/grid-container.tsx | 47 +- components/grid/grid-types.ts | 10 +- components/grid/grid.tsx | 33 +- components/grid/index.ts | 17 +- .../__snapshots__/browser.test.tsx.snap | 3179 ++++++-- components/image/__tests__/index.test.tsx | 25 - components/image/image-browser-https-icon.tsx | 8 +- components/image/image-browser.tsx | 73 +- components/image/image.skeleton.tsx | 11 +- components/image/image.tsx | 87 +- components/image/index.ts | 9 +- components/image/styles.ts | 2 +- components/index.ts | 227 +- .../__snapshots__/index.test.tsx.snap | 514 +- .../__snapshots__/password.test.tsx.snap | 31 +- components/input/__tests__/index.test.tsx | 18 +- components/input/index.ts | 15 +- components/input/input-block-label.tsx | 16 +- components/input/input-icon-clear.tsx | 24 +- components/input/input-icon.tsx | 36 +- components/input/input-label.tsx | 4 +- components/input/input-props.ts | 15 +- components/input/input.tsx | 81 +- components/input/password-icon.tsx | 2 - components/input/password.tsx | 84 +- components/input/styles.ts | 30 +- .../__snapshots__/index.test.tsx.snap | 270 +- components/keyboard/__tests__/index.test.tsx | 7 +- components/keyboard/index.ts | 3 +- components/keyboard/keyboard.tsx | 65 +- .../__snapshots__/index.test.tsx.snap | 67 +- components/link/icon.tsx | 8 +- components/link/index.ts | 3 +- components/link/link.tsx | 47 +- .../__snapshots__/index.test.tsx.snap | 438 +- components/loading/__tests__/index.test.tsx | 17 +- components/loading/index.ts | 1 + components/loading/loading.tsx | 87 +- .../__snapshots__/index.test.tsx.snap | 93 +- components/modal/__tests__/index.test.tsx | 95 +- components/modal/index.ts | 22 +- components/modal/modal-action.tsx | 45 +- components/modal/modal-actions.tsx | 26 +- components/modal/modal-content.tsx | 31 +- components/modal/modal-subtitle.tsx | 26 +- components/modal/modal-title.tsx | 25 +- components/modal/modal-wrapper.tsx | 26 +- components/modal/modal.tsx | 85 +- components/modal/use-modal.ts | 10 +- .../__snapshots__/index.test.tsx.snap | 101 +- components/note/__tests__/index.test.tsx | 7 +- components/note/index.ts | 3 +- components/note/note.tsx | 41 +- .../__snapshots__/child.test.tsx.snap | 24 +- .../__snapshots__/index.test.tsx.snap | 78 +- components/page/__tests__/index.test.tsx | 13 - components/page/index.ts | 20 +- components/page/page-content.tsx | 23 +- components/page/page-footer.tsx | 22 +- components/page/page-header.tsx | 21 +- components/page/page.tsx | 46 +- components/page/styles.ts | 15 - .../__snapshots__/pagination.test.tsx.snap | 16 +- components/pagination/index.ts | 13 +- components/pagination/pagination-ellipsis.tsx | 5 +- components/pagination/pagination-item.tsx | 3 +- components/pagination/pagination-next.tsx | 1 + components/pagination/pagination-pages.tsx | 1 + components/pagination/pagination-previous.tsx | 5 +- components/pagination/pagination.tsx | 66 +- .../__snapshots__/index.test.tsx.snap | 18 +- components/popover/__tests__/index.test.tsx | 95 + components/popover/index.ts | 12 +- components/popover/popover-context.ts | 15 + components/popover/popover-item.tsx | 77 +- components/popover/popover.tsx | 103 +- .../__snapshots__/index.test.tsx.snap | 60 +- components/progress/index.ts | 1 + components/progress/progress.tsx | 35 +- .../__snapshots__/group.test.tsx.snap | 291 +- .../__snapshots__/index.test.tsx.snap | 104 +- components/radio/__tests__/group.test.tsx | 18 - components/radio/__tests__/index.test.tsx | 11 +- components/radio/index.ts | 16 +- components/radio/radio-description.tsx | 26 +- components/radio/radio-group.tsx | 42 +- components/radio/radio.tsx | 60 +- components/radio/styles.ts | 44 + .../__snapshots__/index.test.tsx.snap | 362 + components/rating/__tests__/index.test.tsx | 108 + components/rating/index.ts | 4 + components/rating/rating-icon.tsx | 21 + components/rating/rating.tsx | 140 + components/row/__tests__/index.test.tsx | 3 +- components/row/index.ts | 3 +- components/row/row.tsx | 11 +- .../__snapshots__/index.test.tsx.snap | 3585 ++++++--- .../__snapshots__/multiple.test.tsx.snap | 180 +- components/select/__tests__/events.test.tsx | 66 + components/select/__tests__/index.test.tsx | 38 +- components/select/index.ts | 9 +- components/select/select-context.ts | 3 - components/select/select-dropdown.tsx | 92 +- components/select/select-icon-clear.tsx | 15 +- components/select/select-icon.tsx | 23 +- components/select/select-input.tsx | 56 + components/select/select-multiple-value.tsx | 11 +- components/select/select-option.tsx | 54 +- components/select/select.tsx | 473 +- components/select/styles.ts | 65 +- .../__snapshots__/transition.test.tsx.snap | 2 +- components/shared/__tests__/backdrop.test.tsx | 6 +- .../shared/__tests__/transition.test.tsx | 20 +- components/shared/backdrop.tsx | 31 +- components/shared/css-transition.tsx | 11 +- components/shared/dropdown.tsx | 27 +- components/shared/expand.tsx | 11 +- .../__snapshots__/index.test.tsx.snap | 459 +- components/slider/__tests__/index.test.tsx | 16 + components/slider/index.ts | 1 + components/slider/slider-dot.tsx | 104 +- components/slider/slider.tsx | 47 +- components/slider/styles.ts | 32 + .../__snapshots__/index.test.tsx.snap | 226 +- components/snippet/index.ts | 2 + components/snippet/snippet-icon.tsx | 14 +- components/snippet/snippet.tsx | 63 +- components/snippet/styles.ts | 4 +- .../__snapshots__/index.test.tsx.snap | 96 +- components/spacer/__tests__/index.test.tsx | 16 +- components/spacer/index.ts | 3 +- components/spacer/spacer.tsx | 36 +- .../__snapshots__/index.test.tsx.snap | 1008 +-- components/spinner/__tests__/index.test.tsx | 7 +- components/spinner/index.ts | 1 + components/spinner/spinner.tsx | 41 +- .../__snapshots__/index.test.tsx.snap | 235 +- components/table/__tests__/index.test.tsx | 74 +- components/table/index.ts | 14 +- components/table/table-body.tsx | 49 +- components/table/table-cell.tsx | 62 +- components/table/table-column.tsx | 54 +- components/table/table-context.ts | 22 +- components/table/table-head.tsx | 38 +- components/table/table-types.ts | 32 + components/table/table.tsx | 138 +- .../__snapshots__/index.test.tsx.snap | 163 +- components/tabs/__tests__/index.test.tsx | 3 +- components/tabs/index.ts | 11 +- components/tabs/tabs-context.ts | 14 +- components/tabs/tabs-item.tsx | 105 +- components/tabs/tabs.tsx | 139 +- .../__snapshots__/index.test.tsx.snap | 602 +- components/tag/index.ts | 3 +- components/tag/tag.tsx | 42 +- .../__snapshots__/index.test.tsx.snap | 568 +- components/text/__tests__/index.test.tsx | 4 +- components/text/child.tsx | 88 +- components/text/index.ts | 3 +- components/text/text.tsx | 40 +- .../__snapshots__/index.test.tsx.snap | 84 +- components/textarea/__tests__/index.test.tsx | 4 +- components/textarea/index.ts | 1 + components/textarea/textarea.tsx | 58 +- components/themes/index.ts | 10 + components/themes/presets/index.ts | 1 + components/themes/presets/shared.ts | 1 + .../__snapshots__/index.test.tsx.snap | 422 +- components/toggle/__tests__/index.test.tsx | 20 +- components/toggle/index.ts | 7 + components/toggle/styles.ts | 32 + components/toggle/toggle.tsx | 76 +- components/tooltip/__test__/index.test.tsx | 8 +- components/tooltip/helper.ts | 33 + components/tooltip/index.ts | 7 + components/tooltip/placement.ts | 40 +- components/tooltip/tooltip-content.tsx | 68 +- components/tooltip/tooltip-icon.tsx | 16 +- components/tooltip/tooltip.tsx | 49 +- .../__snapshots__/index.test.tsx.snap | 4 +- components/tree/__tests__/index.test.tsx | 4 +- components/tree/index.ts | 11 +- components/tree/tree-file-icon.tsx | 17 +- components/tree/tree-file.tsx | 9 +- components/tree/tree-folder-icon.tsx | 17 +- components/tree/tree-folder.tsx | 9 +- components/tree/tree-status-icon.tsx | 13 +- components/tree/tree.tsx | 27 +- components/use-all-themes/index.ts | 1 + components/use-body-scroll/index.ts | 1 + components/use-click-away/use-click-away.ts | 13 +- components/use-clipboard/index.ts | 1 + .../use-keyboard/__tests__/keyboard.test.tsx | 177 + components/use-keyboard/codes.ts | 94 + components/use-keyboard/helper.ts | 27 + components/use-keyboard/index.ts | 11 + components/use-keyboard/use-keyboard.ts | 90 + components/use-media-query/index.ts | 1 + .../__tests__/scaleable.test.tsx | 187 + components/use-scaleable/index.ts | 7 + components/use-scaleable/scaleable-context.ts | 100 + components/use-scaleable/utils.ts | 43 + components/use-scaleable/with-scaleable.tsx | 118 + components/use-theme/theme-context.ts | 7 +- .../__snapshots__/index.test.tsx.snap | 38 +- components/use-toasts/index.ts | 1 + components/use-toasts/toast-item.tsx | 2 +- components/use-toasts/use-toast.tsx | 4 +- .../__snapshots__/index.test.tsx.snap | 608 +- components/user/index.ts | 8 +- components/user/user-link.tsx | 47 +- components/user/user.tsx | 42 +- .../utils/__tests__/context-state.test.tsx | 80 - components/utils/collections.ts | 14 + components/utils/prop-types.ts | 8 +- components/utils/use-default-props.ts | 21 + components/utils/use-ssr.ts | 7 +- components/utils/with-defaults.ts | 9 - examples/create-next-app/.gitignore | 30 - examples/create-next-app/README.md | 4 +- examples/create-next-app/next-env.d.ts | 3 + examples/create-next-app/next.config.js | 3 + examples/create-next-app/package.json | 14 +- .../pages/{_app.js => _app.tsx} | 3 +- examples/create-next-app/pages/index.js | 14 - examples/create-next-app/pages/index.tsx | 51 + .../create-next-app/public/geist-banner.png | Bin 0 -> 42007 bytes examples/create-next-app/tsconfig.json | 19 + examples/extends-components/src/my-input.tsx | 2 +- .../attributes/attributes-table.tsx | 91 + .../attributes/attributes-title.tsx | 2 +- lib/components/attributes/attributes.tsx | 104 +- lib/components/attributes/index.ts | 2 + lib/components/controls.tsx | 9 +- lib/components/customization/codes.tsx | 7 +- lib/components/customization/demo.tsx | 22 +- .../customization/editor-color-item.tsx | 3 +- lib/components/customization/editor.tsx | 21 +- lib/components/customization/layout.tsx | 18 +- lib/components/displays/colors.tsx | 11 +- lib/components/example-block.tsx | 19 +- lib/components/grid-demo.tsx | 39 + lib/components/icons/logo.tsx | 8 +- lib/components/index.ts | 6 +- lib/components/layout.tsx | 8 +- lib/components/menu/menu-links.tsx | 40 +- lib/components/menu/menu-sticker.tsx | 66 +- lib/components/playground/dynamic-live.tsx | 11 +- lib/components/playground/editor.tsx | 36 +- lib/components/playground/playground.tsx | 16 +- lib/components/playground/title.tsx | 79 +- lib/components/sidebar/active-catalog.tsx | 12 + lib/components/sidebar/active-link.tsx | 49 +- lib/components/sidebar/index.tsx | 6 +- lib/components/sidebar/tabbar-mobile.tsx | 22 +- lib/config-provider.tsx | 19 +- lib/data/metadata-en-us.json | 2 +- lib/data/metadata-zh-cn.json | 2 +- lib/use-locale.ts | 2 +- next-env.d.ts | 1 + next.config.js | 41 +- package.json | 81 +- pages/_app.tsx | 15 +- pages/en-us/components/auto-complete.mdx | 99 +- pages/en-us/components/avatar.mdx | 38 +- pages/en-us/components/badge.mdx | 85 +- pages/en-us/components/breadcrumbs.mdx | 48 +- pages/en-us/components/button-dropdown.mdx | 88 +- pages/en-us/components/button-group.mdx | 35 +- pages/en-us/components/button.mdx | 76 +- pages/en-us/components/card.mdx | 82 +- pages/en-us/components/checkbox.mdx | 69 +- pages/en-us/components/code.mdx | 21 +- pages/en-us/components/collapse.mdx | 2 +- pages/en-us/components/display.mdx | 23 +- pages/en-us/components/divider.mdx | 48 +- pages/en-us/components/dot.mdx | 14 +- pages/en-us/components/drawer.mdx | 105 + pages/en-us/components/fieldset.mdx | 82 +- pages/en-us/components/file-tree.mdx | 2 +- pages/en-us/components/grid.mdx | 123 +- pages/en-us/components/icons.mdx | 16 +- pages/en-us/components/image.mdx | 13 +- pages/en-us/components/input.mdx | 75 +- pages/en-us/components/keyboard.mdx | 39 +- pages/en-us/components/layout.mdx | 158 - pages/en-us/components/link.mdx | 22 +- pages/en-us/components/loading.mdx | 102 +- pages/en-us/components/modal.mdx | 48 +- pages/en-us/components/note.mdx | 29 +- pages/en-us/components/page.mdx | 11 +- pages/en-us/components/pagination.mdx | 41 +- pages/en-us/components/popover.mdx | 42 +- pages/en-us/components/progress.mdx | 30 +- pages/en-us/components/radio.mdx | 77 +- pages/en-us/components/rating.mdx | 116 + pages/en-us/components/select.mdx | 140 +- pages/en-us/components/slider.mdx | 69 +- pages/en-us/components/snippet.mdx | 38 +- pages/en-us/components/spacer.mdx | 48 +- pages/en-us/components/spinner.mdx | 24 +- pages/en-us/components/table.mdx | 156 +- pages/en-us/components/tabs.mdx | 40 +- pages/en-us/components/tag.mdx | 16 +- pages/en-us/components/text.mdx | 95 +- pages/en-us/components/textarea.mdx | 80 +- pages/en-us/components/toast.mdx | 20 +- pages/en-us/components/toggle.mdx | 50 +- pages/en-us/components/tooltip.mdx | 172 +- pages/en-us/components/use-body-scroll.mdx | 11 +- pages/en-us/components/use-click-away.mdx | 4 +- pages/en-us/components/use-clipboard.mdx | 6 +- pages/en-us/components/use-current-state.mdx | 6 +- pages/en-us/components/use-keyboard.mdx | 81 + pages/en-us/components/use-media-query.mdx | 7 +- pages/en-us/components/user.mdx | 2 +- pages/en-us/customization/index.tsx | 5 +- pages/en-us/guide/colors.mdx | 33 +- pages/en-us/guide/installation.mdx | 52 +- pages/en-us/guide/introduction.mdx | 58 +- pages/en-us/guide/scaleable.mdx | 138 + pages/en-us/guide/server-render.mdx | 16 +- pages/en-us/guide/themes.mdx | 23 +- pages/en-us/index.tsx | 148 + pages/zh-cn/components/auto-complete.mdx | 77 +- pages/zh-cn/components/avatar.mdx | 36 +- pages/zh-cn/components/badge.mdx | 85 +- pages/zh-cn/components/breadcrumbs.mdx | 46 +- pages/zh-cn/components/button-dropdown.mdx | 86 +- pages/zh-cn/components/button-group.mdx | 61 +- pages/zh-cn/components/button.mdx | 86 +- pages/zh-cn/components/card.mdx | 88 +- pages/zh-cn/components/checkbox.mdx | 55 +- pages/zh-cn/components/code.mdx | 21 +- pages/zh-cn/components/display.mdx | 23 +- pages/zh-cn/components/divider.mdx | 46 +- pages/zh-cn/components/dot.mdx | 14 +- pages/zh-cn/components/drawer.mdx | 105 + pages/zh-cn/components/fieldset.mdx | 50 +- pages/zh-cn/components/grid.mdx | 119 +- pages/zh-cn/components/icons.mdx | 6 +- pages/zh-cn/components/image.mdx | 13 +- pages/zh-cn/components/input.mdx | 89 +- pages/zh-cn/components/keyboard.mdx | 23 +- pages/zh-cn/components/layout.mdx | 158 - pages/zh-cn/components/link.mdx | 2 +- pages/zh-cn/components/loading.mdx | 100 +- pages/zh-cn/components/modal.mdx | 32 +- pages/zh-cn/components/note.mdx | 27 +- pages/zh-cn/components/page.mdx | 9 +- pages/zh-cn/components/pagination.mdx | 41 +- pages/zh-cn/components/popover.mdx | 42 +- pages/zh-cn/components/progress.mdx | 30 +- pages/zh-cn/components/radio.mdx | 69 +- pages/zh-cn/components/rating.mdx | 115 + pages/zh-cn/components/select.mdx | 96 +- pages/zh-cn/components/slider.mdx | 15 +- pages/zh-cn/components/snippet.mdx | 38 +- pages/zh-cn/components/spacer.mdx | 42 +- pages/zh-cn/components/spinner.mdx | 24 +- pages/zh-cn/components/table.mdx | 153 +- pages/zh-cn/components/tabs.mdx | 14 +- pages/zh-cn/components/tag.mdx | 16 +- pages/zh-cn/components/text.mdx | 112 +- pages/zh-cn/components/textarea.mdx | 75 +- pages/zh-cn/components/toast.mdx | 8 +- pages/zh-cn/components/toggle.mdx | 34 +- pages/zh-cn/components/tooltip.mdx | 156 +- pages/zh-cn/components/use-body-scroll.mdx | 10 +- pages/zh-cn/components/use-click-away.mdx | 2 +- pages/zh-cn/components/use-clipboard.mdx | 4 +- pages/zh-cn/components/use-current-state.mdx | 4 +- pages/zh-cn/components/use-keyboard.mdx | 81 + pages/zh-cn/components/use-media-query.mdx | 5 +- pages/zh-cn/components/user.mdx | 2 +- pages/zh-cn/customization/index.tsx | 4 +- pages/zh-cn/guide/colors.mdx | 15 +- pages/zh-cn/guide/installation.mdx | 44 +- pages/zh-cn/guide/introduction.mdx | 53 +- pages/zh-cn/guide/scaleable.mdx | 130 + pages/zh-cn/guide/server-render.mdx | 14 +- pages/zh-cn/guide/themes.mdx | 21 +- pages/zh-cn/index.tsx | 148 + tests/__mocks__/styled-jsx/css.js | 10 +- tests/{setup.js => setup.ts} | 5 +- yarn.lock | 6469 ++++++++--------- 504 files changed, 30994 insertions(+), 21706 deletions(-) create mode 100644 components/checkbox/styles.ts create mode 100644 components/drawer/__tests__/__snapshots__/index.test.tsx.snap create mode 100644 components/drawer/__tests__/index.test.tsx create mode 100644 components/drawer/__tests__/use-modal.test.tsx create mode 100644 components/drawer/drawer-wrapper.tsx create mode 100644 components/drawer/drawer.tsx create mode 100644 components/drawer/helper.ts create mode 100644 components/drawer/index.ts delete mode 100644 components/fieldset/fieldset-footer-actions.tsx delete mode 100644 components/fieldset/fieldset-footer-status.tsx delete mode 100644 components/page/styles.ts create mode 100644 components/popover/popover-context.ts create mode 100644 components/radio/styles.ts create mode 100644 components/rating/__tests__/__snapshots__/index.test.tsx.snap create mode 100644 components/rating/__tests__/index.test.tsx create mode 100644 components/rating/index.ts create mode 100644 components/rating/rating-icon.tsx create mode 100644 components/rating/rating.tsx create mode 100644 components/select/__tests__/events.test.tsx create mode 100644 components/select/select-input.tsx create mode 100644 components/slider/styles.ts create mode 100644 components/table/table-types.ts create mode 100644 components/toggle/styles.ts create mode 100644 components/tooltip/helper.ts create mode 100644 components/use-keyboard/__tests__/keyboard.test.tsx create mode 100644 components/use-keyboard/codes.ts create mode 100644 components/use-keyboard/helper.ts create mode 100644 components/use-keyboard/index.ts create mode 100644 components/use-keyboard/use-keyboard.ts create mode 100644 components/use-scaleable/__tests__/scaleable.test.tsx create mode 100644 components/use-scaleable/index.ts create mode 100644 components/use-scaleable/scaleable-context.ts create mode 100644 components/use-scaleable/utils.ts create mode 100644 components/use-scaleable/with-scaleable.tsx delete mode 100644 components/utils/__tests__/context-state.test.tsx create mode 100644 components/utils/use-default-props.ts delete mode 100644 components/utils/with-defaults.ts delete mode 100644 examples/create-next-app/.gitignore create mode 100644 examples/create-next-app/next-env.d.ts create mode 100644 examples/create-next-app/next.config.js rename examples/create-next-app/pages/{_app.js => _app.tsx} (67%) delete mode 100644 examples/create-next-app/pages/index.js create mode 100644 examples/create-next-app/pages/index.tsx create mode 100644 examples/create-next-app/public/geist-banner.png create mode 100644 examples/create-next-app/tsconfig.json create mode 100644 lib/components/attributes/attributes-table.tsx create mode 100644 lib/components/grid-demo.tsx create mode 100644 pages/en-us/components/drawer.mdx delete mode 100644 pages/en-us/components/layout.mdx create mode 100644 pages/en-us/components/rating.mdx create mode 100644 pages/en-us/components/use-keyboard.mdx create mode 100644 pages/en-us/guide/scaleable.mdx create mode 100644 pages/en-us/index.tsx create mode 100644 pages/zh-cn/components/drawer.mdx delete mode 100644 pages/zh-cn/components/layout.mdx create mode 100644 pages/zh-cn/components/rating.mdx create mode 100644 pages/zh-cn/components/use-keyboard.mdx create mode 100644 pages/zh-cn/guide/scaleable.mdx create mode 100644 pages/zh-cn/index.tsx rename tests/{setup.js => setup.ts} (55%) diff --git a/.circleci/config.yml b/.circleci/config.yml index a7b993e41..fd674d2f2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: test: docker: - - image: circleci/node:12.0 + - image: circleci/node:14.15.0 working_directory: ~/repo @@ -27,7 +27,7 @@ jobs: build: docker: - - image: circleci/node:12.0 + - image: circleci/node:14.15.0 working_directory: ~/repo diff --git a/.jest.config.js b/.jest.config.js index e05f68cf3..6050b4ee9 100644 --- a/.jest.config.js +++ b/.jest.config.js @@ -1,18 +1,20 @@ module.exports = { verbose: true, - setupFiles: ['./tests/setup.js'], + testEnvironment: 'jsdom', + + setupFilesAfterEnv: ['./tests/setup.ts'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - testPathIgnorePatterns: ['/pages/', '/dist/', '/lib/'], + testPathIgnorePatterns: ['/pages/', '/dist/', '/lib/', '/esm/'], transform: { '^.+\\.tsx?$': ['babel-jest', { configFile: './tests/.babelrc.js' }], }, testRegex: '.*\\.test\\.(j|t)sx?$', - // testRegex: 'grid\\/.*\\.test\\.(j|t)sx?$', + // testRegex: 'modal\\/.*\\.test\\.(j|t)sx?$', collectCoverageFrom: [ 'components/**/*.{ts,tsx}', diff --git a/components/auto-complete/__tests__/__snapshots__/index.test.tsx.snap b/components/auto-complete/__tests__/__snapshots__/index.test.tsx.snap index eaf1c54ba..5dcac37db 100644 --- a/components/auto-complete/__tests__/__snapshots__/index.test.tsx.snap +++ b/components/auto-complete/__tests__/__snapshots__/index.test.tsx.snap @@ -1,14 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`AutoComplete should render correctly 1`] = ` - -`; +exports[`AutoComplete should render correctly 1`] = ``; diff --git a/components/auto-complete/__tests__/__snapshots__/search.test.tsx.snap b/components/auto-complete/__tests__/__snapshots__/search.test.tsx.snap index 9ae1e5d98..e49c05a99 100644 --- a/components/auto-complete/__tests__/__snapshots__/search.test.tsx.snap +++ b/components/auto-complete/__tests__/__snapshots__/search.test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`AutoComplete Search should hide empty component 1`] = ` -initialize { +LoadedCheerio { "0": Node { "attribs": Object { "class": "auto-complete", @@ -26,9 +26,11 @@ initialize { "attribs": Object { "autocomplete": "off", "class": " ", + "height": "calc(2.25 * 16px)", "placeholder": "Enter here", "type": "text", "value": "", + "width": "initial", }, "children": Array [], "name": "input", @@ -40,16 +42,20 @@ initialize { "x-attribsNamespace": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, "x-attribsPrefix": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, }, ], @@ -76,16 +82,21 @@ initialize { "data": " .with-label { display: inline-block; - width: initial; box-sizing: border-box; -webkit-box-align: center; + --input-height: calc(2.25 * 16px); + font-size: calc(0.875 * 16px); + width: initial; + height: var(--input-height); + padding: 0 0 0 0; + margin: 0 0 0 0; } .input-container { display: inline-flex; align-items: center; width: initial; - height: calc(1.687 * 16pt); + height: var(--input-height); } .input-wrapper { @@ -125,10 +136,10 @@ initialize { } input { - margin: 4px 10px; + margin: 0.25em 0.625em; padding: 0; box-shadow: none; - font-size: .875rem; + font-size: calc(0.875 * 16px); background-color: transparent; border: none; color: #000; @@ -198,16 +209,21 @@ initialize { "data": " .with-label { display: inline-block; - width: initial; box-sizing: border-box; -webkit-box-align: center; + --input-height: calc(2.25 * 16px); + font-size: calc(0.875 * 16px); + width: initial; + height: var(--input-height); + padding: 0 0 0 0; + margin: 0 0 0 0; } .input-container { display: inline-flex; align-items: center; width: initial; - height: calc(1.687 * 16pt); + height: var(--input-height); } .input-wrapper { @@ -247,10 +263,10 @@ initialize { } input { - margin: 4px 10px; + margin: 0.25em 0.625em; padding: 0; box-shadow: none; - font-size: .875rem; + font-size: calc(0.875 * 16px); background-color: transparent; border: none; color: #000; @@ -312,9 +328,11 @@ initialize { "attribs": Object { "autocomplete": "off", "class": " ", + "height": "calc(2.25 * 16px)", "placeholder": "Enter here", "type": "text", "value": "", + "width": "initial", }, "children": Array [], "name": "input", @@ -326,16 +344,20 @@ initialize { "x-attribsNamespace": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, "x-attribsPrefix": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, }, ], @@ -378,16 +400,17 @@ initialize { "children": Array [ Node { "data": " - .auto-complete { - width: max-content; - } - - .auto-complete :global(.loading) { - left: -3px; - right: -3px; - width: max-content; - } - ", + .auto-complete { + width: max-content; + height: auto; + padding: 0 0 0 0; + margin: 0 0 0 0; + } + + .auto-complete :global(.loading) { + width: max-content; + } + ", "next": null, "parent": [Circular], "prev": null, @@ -418,16 +441,17 @@ initialize { "children": Array [ Node { "data": " - .auto-complete { - width: max-content; - } - - .auto-complete :global(.loading) { - left: -3px; - right: -3px; - width: max-content; - } - ", + .auto-complete { + width: max-content; + height: auto; + padding: 0 0 0 0; + margin: 0 0 0 0; + } + + .auto-complete :global(.loading) { + width: max-content; + } + ", "next": null, "parent": [Circular], "prev": null, @@ -457,9 +481,11 @@ initialize { "attribs": Object { "autocomplete": "off", "class": " ", + "height": "calc(2.25 * 16px)", "placeholder": "Enter here", "type": "text", "value": "", + "width": "initial", }, "children": Array [], "name": "input", @@ -471,16 +497,20 @@ initialize { "x-attribsNamespace": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, "x-attribsPrefix": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, }, ], @@ -507,16 +537,21 @@ initialize { "data": " .with-label { display: inline-block; - width: initial; box-sizing: border-box; -webkit-box-align: center; + --input-height: calc(2.25 * 16px); + font-size: calc(0.875 * 16px); + width: initial; + height: var(--input-height); + padding: 0 0 0 0; + margin: 0 0 0 0; } .input-container { display: inline-flex; align-items: center; width: initial; - height: calc(1.687 * 16pt); + height: var(--input-height); } .input-wrapper { @@ -556,10 +591,10 @@ initialize { } input { - margin: 4px 10px; + margin: 0.25em 0.625em; padding: 0; box-shadow: none; - font-size: .875rem; + font-size: calc(0.875 * 16px); background-color: transparent; border: none; color: #000; @@ -629,16 +664,21 @@ initialize { "data": " .with-label { display: inline-block; - width: initial; box-sizing: border-box; -webkit-box-align: center; + --input-height: calc(2.25 * 16px); + font-size: calc(0.875 * 16px); + width: initial; + height: var(--input-height); + padding: 0 0 0 0; + margin: 0 0 0 0; } .input-container { display: inline-flex; align-items: center; width: initial; - height: calc(1.687 * 16pt); + height: var(--input-height); } .input-wrapper { @@ -678,10 +718,10 @@ initialize { } input { - margin: 4px 10px; + margin: 0.25em 0.625em; padding: 0; box-shadow: none; - font-size: .875rem; + font-size: calc(0.875 * 16px); background-color: transparent; border: none; color: #000; @@ -743,9 +783,11 @@ initialize { "attribs": Object { "autocomplete": "off", "class": " ", + "height": "calc(2.25 * 16px)", "placeholder": "Enter here", "type": "text", "value": "", + "width": "initial", }, "children": Array [], "name": "input", @@ -757,16 +799,20 @@ initialize { "x-attribsNamespace": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, "x-attribsPrefix": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, }, ], @@ -842,7 +888,83 @@ initialize { "class": undefined, }, }, - "_root": [Circular], + "_root": LoadedCheerio { + "0": Node { + "children": Array [ + Node { + "attribs": Object {}, + "children": Array [ + Node { + "attribs": Object {}, + "children": Array [], + "name": "head", + "namespace": "http://www.w3.org/1999/xhtml", + "next": Node { + "attribs": Object {}, + "children": Array [], + "name": "body", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": [Circular], + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + Node { + "attribs": Object {}, + "children": Array [], + "name": "body", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": Node { + "attribs": Object {}, + "children": Array [], + "name": "head", + "namespace": "http://www.w3.org/1999/xhtml", + "next": [Circular], + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + ], + "name": "html", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + ], + "name": "root", + "next": null, + "parent": null, + "prev": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": Object { + "decodeEntities": true, + "xml": false, + }, + }, "length": 1, "options": Object { "decodeEntities": true, @@ -852,7 +974,7 @@ initialize { `; exports[`AutoComplete Search should hide empty component 2`] = ` -initialize { +LoadedCheerio { "0": Node { "attribs": Object { "class": "auto-complete", @@ -877,9 +999,11 @@ initialize { "attribs": Object { "autocomplete": "off", "class": " ", + "height": "calc(2.25 * 16px)", "placeholder": "Enter here", "type": "text", "value": "", + "width": "initial", }, "children": Array [], "name": "input", @@ -891,16 +1015,20 @@ initialize { "x-attribsNamespace": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, "x-attribsPrefix": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, }, ], @@ -927,16 +1055,21 @@ initialize { "data": " .with-label { display: inline-block; - width: initial; box-sizing: border-box; -webkit-box-align: center; + --input-height: calc(2.25 * 16px); + font-size: calc(0.875 * 16px); + width: initial; + height: var(--input-height); + padding: 0 0 0 0; + margin: 0 0 0 0; } .input-container { display: inline-flex; align-items: center; width: initial; - height: calc(1.687 * 16pt); + height: var(--input-height); } .input-wrapper { @@ -976,10 +1109,10 @@ initialize { } input { - margin: 4px 10px; + margin: 0.25em 0.625em; padding: 0; box-shadow: none; - font-size: .875rem; + font-size: calc(0.875 * 16px); background-color: transparent; border: none; color: #000; @@ -1049,16 +1182,21 @@ initialize { "data": " .with-label { display: inline-block; - width: initial; box-sizing: border-box; -webkit-box-align: center; + --input-height: calc(2.25 * 16px); + font-size: calc(0.875 * 16px); + width: initial; + height: var(--input-height); + padding: 0 0 0 0; + margin: 0 0 0 0; } .input-container { display: inline-flex; align-items: center; width: initial; - height: calc(1.687 * 16pt); + height: var(--input-height); } .input-wrapper { @@ -1098,10 +1236,10 @@ initialize { } input { - margin: 4px 10px; + margin: 0.25em 0.625em; padding: 0; box-shadow: none; - font-size: .875rem; + font-size: calc(0.875 * 16px); background-color: transparent; border: none; color: #000; @@ -1163,9 +1301,11 @@ initialize { "attribs": Object { "autocomplete": "off", "class": " ", + "height": "calc(2.25 * 16px)", "placeholder": "Enter here", "type": "text", "value": "", + "width": "initial", }, "children": Array [], "name": "input", @@ -1177,16 +1317,20 @@ initialize { "x-attribsNamespace": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, "x-attribsPrefix": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, }, ], @@ -1229,16 +1373,17 @@ initialize { "children": Array [ Node { "data": " - .auto-complete { - width: max-content; - } - - .auto-complete :global(.loading) { - left: -3px; - right: -3px; - width: max-content; - } - ", + .auto-complete { + width: max-content; + height: auto; + padding: 0 0 0 0; + margin: 0 0 0 0; + } + + .auto-complete :global(.loading) { + width: max-content; + } + ", "next": null, "parent": [Circular], "prev": null, @@ -1269,16 +1414,17 @@ initialize { "children": Array [ Node { "data": " - .auto-complete { - width: max-content; - } - - .auto-complete :global(.loading) { - left: -3px; - right: -3px; - width: max-content; - } - ", + .auto-complete { + width: max-content; + height: auto; + padding: 0 0 0 0; + margin: 0 0 0 0; + } + + .auto-complete :global(.loading) { + width: max-content; + } + ", "next": null, "parent": [Circular], "prev": null, @@ -1308,9 +1454,11 @@ initialize { "attribs": Object { "autocomplete": "off", "class": " ", + "height": "calc(2.25 * 16px)", "placeholder": "Enter here", "type": "text", "value": "", + "width": "initial", }, "children": Array [], "name": "input", @@ -1322,16 +1470,20 @@ initialize { "x-attribsNamespace": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, "x-attribsPrefix": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, }, ], @@ -1358,16 +1510,21 @@ initialize { "data": " .with-label { display: inline-block; - width: initial; box-sizing: border-box; -webkit-box-align: center; + --input-height: calc(2.25 * 16px); + font-size: calc(0.875 * 16px); + width: initial; + height: var(--input-height); + padding: 0 0 0 0; + margin: 0 0 0 0; } .input-container { display: inline-flex; align-items: center; width: initial; - height: calc(1.687 * 16pt); + height: var(--input-height); } .input-wrapper { @@ -1407,10 +1564,10 @@ initialize { } input { - margin: 4px 10px; + margin: 0.25em 0.625em; padding: 0; box-shadow: none; - font-size: .875rem; + font-size: calc(0.875 * 16px); background-color: transparent; border: none; color: #000; @@ -1480,16 +1637,21 @@ initialize { "data": " .with-label { display: inline-block; - width: initial; box-sizing: border-box; -webkit-box-align: center; + --input-height: calc(2.25 * 16px); + font-size: calc(0.875 * 16px); + width: initial; + height: var(--input-height); + padding: 0 0 0 0; + margin: 0 0 0 0; } .input-container { display: inline-flex; align-items: center; width: initial; - height: calc(1.687 * 16pt); + height: var(--input-height); } .input-wrapper { @@ -1529,10 +1691,10 @@ initialize { } input { - margin: 4px 10px; + margin: 0.25em 0.625em; padding: 0; box-shadow: none; - font-size: .875rem; + font-size: calc(0.875 * 16px); background-color: transparent; border: none; color: #000; @@ -1594,9 +1756,11 @@ initialize { "attribs": Object { "autocomplete": "off", "class": " ", + "height": "calc(2.25 * 16px)", "placeholder": "Enter here", "type": "text", "value": "", + "width": "initial", }, "children": Array [], "name": "input", @@ -1608,16 +1772,20 @@ initialize { "x-attribsNamespace": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, "x-attribsPrefix": Object { "autocomplete": undefined, "class": undefined, + "height": undefined, "placeholder": undefined, "type": undefined, "value": undefined, + "width": undefined, }, }, ], @@ -1693,7 +1861,83 @@ initialize { "class": undefined, }, }, - "_root": [Circular], + "_root": LoadedCheerio { + "0": Node { + "children": Array [ + Node { + "attribs": Object {}, + "children": Array [ + Node { + "attribs": Object {}, + "children": Array [], + "name": "head", + "namespace": "http://www.w3.org/1999/xhtml", + "next": Node { + "attribs": Object {}, + "children": Array [], + "name": "body", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": [Circular], + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + Node { + "attribs": Object {}, + "children": Array [], + "name": "body", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": Node { + "attribs": Object {}, + "children": Array [], + "name": "head", + "namespace": "http://www.w3.org/1999/xhtml", + "next": [Circular], + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + ], + "name": "html", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + ], + "name": "root", + "next": null, + "parent": null, + "prev": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": Object { + "decodeEntities": true, + "xml": false, + }, + }, "length": 1, "options": Object { "decodeEntities": true, diff --git a/components/auto-complete/__tests__/index.test.tsx b/components/auto-complete/__tests__/index.test.tsx index 911bc009b..214abb334 100644 --- a/components/auto-complete/__tests__/index.test.tsx +++ b/components/auto-complete/__tests__/index.test.tsx @@ -14,10 +14,10 @@ describe('AutoComplete', () => { it('should support sizes and status', () => { const wrapper = mount(
- - - - + + + +
, ) expect(() => wrapper.unmount()).not.toThrow() @@ -56,4 +56,11 @@ describe('AutoComplete', () => { expect(wrapper.prop('width')).toEqual('200px') }) + + it('should forward ref by default', () => { + const ref = React.createRef() + const wrapper = mount() + expect(ref.current).not.toBeNull() + expect(() => wrapper.unmount()).not.toThrow() + }) }) diff --git a/components/auto-complete/auto-complete-context.ts b/components/auto-complete/auto-complete-context.ts index 6f2c564a0..618ee59b7 100644 --- a/components/auto-complete/auto-complete-context.ts +++ b/components/auto-complete/auto-complete-context.ts @@ -1,18 +1,15 @@ import React, { MutableRefObject } from 'react' -import { NormalSizes } from '../utils/prop-types' export interface AutoCompleteConfig { value?: string updateValue?: (val: string) => unknown visible?: boolean updateVisible?: (next: boolean) => unknown - size: NormalSizes ref?: MutableRefObject } const defaultContext = { visible: false, - size: 'medium' as NormalSizes, } export const AutoCompleteContext = React.createContext(defaultContext) diff --git a/components/auto-complete/auto-complete-dropdown.tsx b/components/auto-complete/auto-complete-dropdown.tsx index 5f51550aa..ca427743a 100644 --- a/components/auto-complete/auto-complete-dropdown.tsx +++ b/components/auto-complete/auto-complete-dropdown.tsx @@ -1,6 +1,5 @@ -import React, { CSSProperties } from 'react' +import React, { CSSProperties, useMemo } from 'react' import useTheme from '../use-theme' -import withDefaults from '../utils/with-defaults' import { useAutoCompleteContext } from './auto-complete-context' import Dropdown from '../shared/dropdown' @@ -9,6 +8,7 @@ interface Props { className?: string disableMatchWidth?: boolean dropdownStyle?: CSSProperties + getPopupContainer?: () => HTMLElement | null } const defaultProps = { @@ -17,13 +17,23 @@ const defaultProps = { } type NativeAttrs = Omit, keyof Props> -export type AutoCompleteDropdownProps = Props & typeof defaultProps & NativeAttrs +export type AutoCompleteDropdownProps = Props & NativeAttrs const AutoCompleteDropdown: React.FC< React.PropsWithChildren -> = ({ children, visible, className, dropdownStyle, disableMatchWidth }) => { +> = ({ + children, + visible, + className, + dropdownStyle, + disableMatchWidth, + getPopupContainer, +}: React.PropsWithChildren & typeof defaultProps) => { const theme = useTheme() const { ref } = useAutoCompleteContext() + const isEmpty = useMemo(() => { + return !visible || React.Children.count(children) === 0 + }, [children, visible]) const clickHandler = (event: React.MouseEvent) => { event.preventDefault() event.stopPropagation() @@ -31,7 +41,11 @@ const AutoCompleteDropdown: React.FC< } return ( - +
{` .auto-complete-dropdown { border-radius: ${theme.layout.radius}; - box-shadow: ${theme.expressiveness.shadowLarge}; + box-shadow: ${isEmpty ? 'none' : theme.expressiveness.shadowLarge}; background-color: ${theme.palette.background}; overflow-y: auto; max-height: 15rem; @@ -52,4 +66,6 @@ const AutoCompleteDropdown: React.FC< ) } -export default withDefaults(AutoCompleteDropdown, defaultProps) +AutoCompleteDropdown.defaultProps = defaultProps +AutoCompleteDropdown.displayName = 'GeistAutoCompleteDropdown' +export default AutoCompleteDropdown diff --git a/components/auto-complete/auto-complete-empty.tsx b/components/auto-complete/auto-complete-empty.tsx index 28b0b9a95..859342dbe 100644 --- a/components/auto-complete/auto-complete-empty.tsx +++ b/components/auto-complete/auto-complete-empty.tsx @@ -1,5 +1,4 @@ import React from 'react' -import withDefaults from '../utils/with-defaults' import AutoCompleteSearch from './auto-complete-searching' interface Props { @@ -12,17 +11,18 @@ const defaultProps = { className: '', } -export type AutoCompleteEmptyProps = Props & - typeof defaultProps & - React.HTMLAttributes +export type AutoCompleteEmptyProps = Props & React.HTMLAttributes const AutoCompleteEmpty: React.FC> = ({ children, hidden, className, -}) => { +}: React.PropsWithChildren & typeof defaultProps) => { if (hidden) return null return {children} } -export default withDefaults(AutoCompleteEmpty, defaultProps) +AutoCompleteEmpty.defaultProps = defaultProps +AutoCompleteEmpty.displayName = 'GeistAutoCompleteEmpty' + +export default AutoCompleteEmpty diff --git a/components/auto-complete/auto-complete-item.tsx b/components/auto-complete/auto-complete-item.tsx index f75937c9c..f3ce59823 100644 --- a/components/auto-complete/auto-complete-item.tsx +++ b/components/auto-complete/auto-complete-item.tsx @@ -1,60 +1,39 @@ import React, { useMemo } from 'react' -import withDefaults from '../utils/with-defaults' import useTheme from '../use-theme' import { useAutoCompleteContext } from './auto-complete-context' -import { NormalSizes } from '../utils/prop-types' import Ellipsis from '../shared/ellipsis' +import useScaleable, { withScaleable } from '../use-scaleable' interface Props { value: string + // The 'isLabelOnly' is only used inside the component, + // Automatically adjust width when only label children is included. isLabelOnly?: boolean } const defaultProps = {} -export type AutoCompleteItemProps = Props & - typeof defaultProps & - React.HTMLAttributes - -const getSizes = (size: NormalSizes) => { - const fontSizes: { [key in NormalSizes]: string } = { - mini: '.7rem', - small: '.75rem', - medium: '.875rem', - large: '1rem', - } - return fontSizes[size] -} +export type AutoCompleteItemProps = Props & React.HTMLAttributes -const AutoCompleteItem: React.FC> = ({ +const AutoCompleteItemComponent: React.FC< + React.PropsWithChildren +> = ({ value: identValue, children, isLabelOnly, -}) => { +}: React.PropsWithChildren & typeof defaultProps) => { const theme = useTheme() - const { value, updateValue, size, updateVisible } = useAutoCompleteContext() + const { SCALES } = useScaleable() + const { value, updateValue, updateVisible } = useAutoCompleteContext() const selectHandler = () => { updateValue && updateValue(identValue) updateVisible && updateVisible(false) } - const isActive = useMemo(() => value === identValue, [identValue, value]) - const fontSize = useMemo(() => getSizes(size), [size]) - - // The 'isLabelOnly' is only used inside the component, - // Automatically adjust width when only label children is included. - const itemHeight = useMemo(() => { - if (isLabelOnly) return `calc(1.688 * ${theme.layout.gap})` - return 'auto' - }, [isLabelOnly, theme.layout.gap]) return (
- {isLabelOnly ? ( - {children} - ) : ( - children - )} + {isLabelOnly ? {children} : children}
) } -export default withDefaults(AutoCompleteSearch, defaultProps) +AutoCompleteSearchComponent.defaultProps = defaultProps +AutoCompleteSearchComponent.displayName = 'GeistAutoCompleteSearch' +const AutoCompleteSearch = withScaleable(AutoCompleteSearchComponent) + +export default AutoCompleteSearch diff --git a/components/auto-complete/auto-complete.tsx b/components/auto-complete/auto-complete.tsx index 16611b4c0..dc1201a11 100644 --- a/components/auto-complete/auto-complete.tsx +++ b/components/auto-complete/auto-complete.tsx @@ -1,14 +1,24 @@ -import React, { CSSProperties, useEffect, useMemo, useRef, useState } from 'react' +import React, { + CSSProperties, + useEffect, + useImperativeHandle, + useMemo, + useRef, + useState, +} from 'react' import Input from '../input' import AutoCompleteItem, { AutoCompleteItemProps } from './auto-complete-item' import AutoCompleteDropdown from './auto-complete-dropdown' import AutoCompleteSearching from './auto-complete-searching' import AutoCompleteEmpty from './auto-complete-empty' import { AutoCompleteContext, AutoCompleteConfig } from './auto-complete-context' -import { NormalSizes, NormalTypes } from '../utils/prop-types' +import { NormalTypes } from '../utils/prop-types' import Loading from '../loading' import { pickChild } from '../utils/collections' import useCurrentState from '../utils/use-current-state' +import useScaleable, { filterScaleableProps, withScaleable } from '../use-scaleable' + +export type AutoCompleteTypes = NormalTypes export type AutoCompleteOption = { label: string @@ -20,12 +30,10 @@ export type AutoCompleteOptions = Array< > interface Props { - options: AutoCompleteOptions - size?: NormalSizes - status?: NormalTypes + options?: AutoCompleteOptions + type?: AutoCompleteTypes initialValue?: string value?: string - width?: string onChange?: (value: string) => void onSearch?: (value: string) => void onSelect?: (value: string) => void @@ -36,6 +44,7 @@ interface Props { disableMatchWidth?: boolean disableFreeSolo?: boolean className?: string + getPopupContainer?: () => HTMLElement | null } const defaultProps = { @@ -43,14 +52,14 @@ const defaultProps = { initialValue: '', disabled: false, clearable: false, - size: 'medium' as NormalSizes, + type: 'default' as AutoCompleteTypes, disableMatchWidth: false, disableFreeSolo: false, className: '', } type NativeAttrs = Omit, keyof Props> -export type AutoCompleteProps = Props & typeof defaultProps & NativeAttrs +export type AutoCompleteProps = Props & NativeAttrs const childrenToOptionsNode = (options: Array) => options.map((item, index) => { @@ -66,174 +75,176 @@ const childrenToOptionsNode = (options: Array) => // When the search is not set, the "clearable" icon can be displayed in the original location. // When the search is seted, at least one element should exist to avoid re-render. -const getSearchIcon = (searching?: boolean) => { +const getSearchIcon = (searching?: boolean, scale: string | number = 1) => { if (searching === undefined) return null - return searching ? : + return searching ? : } -const AutoComplete: React.FC> = ({ - options, - initialValue: customInitialValue, - onSelect, - onSearch, - onChange, - searching, - children, - size, - status, - value, - width, - clearable, - disabled, - dropdownClassName, - dropdownStyle, - disableMatchWidth, - disableFreeSolo, - ...props -}) => { - const ref = useRef(null) - const inputRef = useRef(null) - const resetTimer = useRef() - const [state, setState, stateRef] = useCurrentState(customInitialValue) - const [selectVal, setSelectVal] = useState(customInitialValue) - const [visible, setVisible] = useState(false) - - const [, searchChild] = pickChild(children, AutoCompleteSearching) - const [, emptyChild] = pickChild(children, AutoCompleteEmpty) - const autoCompleteItems = useMemo(() => { - const hasSearchChild = searchChild && React.Children.count(searchChild) > 0 - const hasEmptyChild = emptyChild && React.Children.count(emptyChild) > 0 - if (searching) { - return hasSearchChild ? ( - searchChild - ) : ( - Searching... - ) +const AutoCompleteComponent = React.forwardRef< + HTMLInputElement, + React.PropsWithChildren +>( + ( + { + options, + initialValue: customInitialValue, + onSelect, + onSearch, + onChange, + searching, + children, + type, + value, + clearable, + disabled, + dropdownClassName, + dropdownStyle, + disableMatchWidth, + disableFreeSolo, + getPopupContainer, + ...props + }: React.PropsWithChildren & typeof defaultProps, + userRef: React.Ref, + ) => { + const resetTimer = useRef() + const { SCALES, getScaleableProps } = useScaleable() + const ref = useRef(null) + const inputRef = useRef(null) + const [state, setState, stateRef] = useCurrentState(customInitialValue) + const [selectVal, setSelectVal] = useState(customInitialValue) + const [visible, setVisible] = useState(false) + useImperativeHandle(userRef, () => inputRef.current) + + const [, searchChild] = pickChild(children, AutoCompleteSearching) + const [, emptyChild] = pickChild(children, AutoCompleteEmpty) + const autoCompleteItems = useMemo(() => { + const hasSearchChild = searchChild && React.Children.count(searchChild) > 0 + const hasEmptyChild = emptyChild && React.Children.count(emptyChild) > 0 + if (searching) { + return hasSearchChild ? ( + searchChild + ) : ( + Searching... + ) + } + if (options.length === 0) { + if (state === '') return null + return hasEmptyChild ? ( + emptyChild + ) : ( + No Options + ) + } + return childrenToOptionsNode(options as Array) + }, [searching, options]) + const showClearIcon = useMemo( + () => clearable && searching === undefined, + [clearable, searching], + ) + + const updateValue = (val: string) => { + if (disabled) return + setSelectVal(val) + onSelect && onSelect(val) + setState(val) + inputRef.current && inputRef.current.focus() } - if (options.length === 0) { - if (state === '') return null - return hasEmptyChild ? ( - emptyChild - ) : ( - No Options - ) + const updateVisible = (next: boolean) => setVisible(next) + const onInputChange = (event: React.ChangeEvent) => { + setVisible(true) + onSearch && onSearch(event.target.value) + setState(event.target.value) } - return childrenToOptionsNode(options as Array) - }, [searching, options]) - const showClearIcon = useMemo(() => clearable && searching === undefined, [ - clearable, - searching, - ]) - - const updateValue = (val: string) => { - if (disabled) return - setSelectVal(val) - onSelect && onSelect(val) - setState(val) - inputRef.current && inputRef.current.focus() - } - const updateVisible = (next: boolean) => setVisible(next) - const onInputChange = (event: React.ChangeEvent) => { - setVisible(true) - onSearch && onSearch(event.target.value) - setState(event.target.value) - } - const resetInputValue = () => { - if (!disableFreeSolo) return - if (!state || state === '') return - if (state !== selectVal) { - setState(selectVal) + const resetInputValue = () => { + if (!disableFreeSolo) return + if (!state || state === '') return + if (state !== selectVal) { + setState(selectVal) + } + } + + useEffect(() => { + onChange && onChange(state) + }, [state]) + useEffect(() => { + if (value === undefined) return + setState(value) + }, [value]) + + const initialValue = useMemo( + () => ({ + ref, + value: state, + updateValue, + visible, + updateVisible, + }), + [state, visible], + ) + + const toggleFocusHandler = (next: boolean) => { + clearTimeout(resetTimer.current) + setVisible(next) + if (next) { + onSearch && onSearch(stateRef.current) + } else { + resetTimer.current = window.setTimeout(() => { + resetInputValue() + clearTimeout(resetTimer.current) + }, 100) + } } - } - - useEffect(() => { - onChange && onChange(state) - }, [state]) - useEffect(() => { - if (value === undefined) return - setState(value) - }, [value]) - - const initialValue = useMemo( - () => ({ - ref, - size, + + const inputProps = { + ...filterScaleableProps(props), + disabled, value: state, - updateValue, - visible, - updateVisible, - }), - [state, visible, size], - ) - - const toggleFocusHandler = (next: boolean) => { - clearTimeout(resetTimer.current) - setVisible(next) - if (next) { - onSearch && onSearch(stateRef.current) - } else { - resetTimer.current = window.setTimeout(() => { - resetInputValue() - clearTimeout(resetTimer.current) - }, 100) } - } - - const inputProps = { - ...props, - width, - disabled, - value: state, - } - - return ( - -
- toggleFocusHandler(true)} - onBlur={() => toggleFocusHandler(false)} - clearable={showClearIcon} - iconRight={getSearchIcon(searching)} - {...inputProps} - /> - - {autoCompleteItems} - - - -
-
- ) -} -type AutoCompleteComponent

= React.FC

& { - Item: typeof AutoCompleteItem - Option: typeof AutoCompleteItem - Searching: typeof AutoCompleteSearching - Empty: typeof AutoCompleteEmpty -} + return ( + +

+ toggleFocusHandler(true)} + onBlur={() => toggleFocusHandler(false)} + clearable={showClearIcon} + width={SCALES.width(1, 'initial')} + height={SCALES.height(2.25)} + iconRight={getSearchIcon(searching, getScaleableProps('scale'))} + {...inputProps} + /> + + {autoCompleteItems} + + + +
+ + ) + }, +) -type ComponentProps = Partial & - Omit & - NativeAttrs -;(AutoComplete as AutoCompleteComponent).defaultProps = defaultProps +AutoCompleteComponent.defaultProps = defaultProps +AutoCompleteComponent.displayName = 'GeistAutoComplete' +const AutoComplete = withScaleable(AutoCompleteComponent) -export default AutoComplete as AutoCompleteComponent +export default AutoComplete diff --git a/components/auto-complete/index.ts b/components/auto-complete/index.ts index 32f953d10..ca95d1178 100644 --- a/components/auto-complete/index.ts +++ b/components/auto-complete/index.ts @@ -3,9 +3,21 @@ import AutoCompleteItem from './auto-complete-item' import AutoCompleteSearching from './auto-complete-searching' import AutoCompleteEmpty from './auto-complete-empty' -AutoComplete.Item = AutoCompleteItem -AutoComplete.Option = AutoCompleteItem -AutoComplete.Searching = AutoCompleteSearching -AutoComplete.Empty = AutoCompleteEmpty +export type AutoCompleteComponentType = typeof AutoComplete & { + Item: typeof AutoCompleteItem + Option: typeof AutoCompleteItem + Searching: typeof AutoCompleteSearching + Empty: typeof AutoCompleteEmpty +} +;(AutoComplete as AutoCompleteComponentType).Item = AutoCompleteItem +;(AutoComplete as AutoCompleteComponentType).Option = AutoCompleteItem +;(AutoComplete as AutoCompleteComponentType).Searching = AutoCompleteSearching +;(AutoComplete as AutoCompleteComponentType).Empty = AutoCompleteEmpty -export default AutoComplete +export type { + AutoCompleteOption, + AutoCompleteOptions, + AutoCompleteProps, + AutoCompleteTypes, +} from './auto-complete' +export default AutoComplete as AutoCompleteComponentType diff --git a/components/avatar/__tests__/__snapshots__/index.test.tsx.snap b/components/avatar/__tests__/__snapshots__/index.test.tsx.snap index 31c1be9d9..246c1718e 100644 --- a/components/avatar/__tests__/__snapshots__/index.test.tsx.snap +++ b/components/avatar/__tests__/__snapshots__/index.test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Avatar should render component of a specified size 1`] = ` -initialize { +exports[`Avatar should render text element 1`] = ` +LoadedCheerio { "0": Node { "attribs": Object { "class": "avatar ", @@ -20,8 +20,6 @@ initialize { Node { "data": " .avatar { - width: 20px; - height: 20px; display: inline-block; position: relative; overflow: hidden; @@ -29,26 +27,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -86,8 +85,6 @@ initialize { Node { "data": " .avatar { - width: 20px; - height: 20px; display: inline-block; position: relative; overflow: hidden; @@ -95,26 +92,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -176,192 +174,83 @@ initialize { "class": undefined, }, }, - "_root": [Circular], - "length": 1, - "options": Object { - "decodeEntities": true, - "xml": false, - }, -} -`; - -exports[`Avatar should render text element 1`] = ` -initialize { - "0": Node { - "attribs": Object { - "class": "avatar ", - }, - "children": Array [ - Node { - "attribs": Object { - "class": "avatar-text", - }, - "children": Array [], - "name": "span", - "namespace": "http://www.w3.org/1999/xhtml", - "next": Node { + "_root": LoadedCheerio { + "0": Node { + "children": Array [ + Node { "attribs": Object {}, "children": Array [ Node { - "data": " - .avatar { - width: 1.875rem; - height: 1.875rem; - display: inline-block; - position: relative; - overflow: hidden; - border: 1px solid #eaeaea; - border-radius: 50%; - vertical-align: top; - background-color: #fff; - margin: 0 0 0 0; - } - - .avatar:first-child { - margin: 0; - } - - .avatar-img { - display: inline-block; - object-fit: cover; - width: 100%; - height: 100%; - border-radius: 50%; - } - - .avatar-text { - position: absolute; - left: 50%; - top: 50%; - font-size: 1em; - text-align: center; - transform: translate(-50%, -50%) scale(0.65); - white-space: nowrap; - user-select: none; - } - ", - "next": null, + "attribs": Object {}, + "children": Array [], + "name": "head", + "namespace": "http://www.w3.org/1999/xhtml", + "next": Node { + "attribs": Object {}, + "children": Array [], + "name": "body", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": [Circular], + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, "parent": [Circular], "prev": null, - "type": "text", + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + Node { + "attribs": Object {}, + "children": Array [], + "name": "body", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": Node { + "attribs": Object {}, + "children": Array [], + "name": "head", + "namespace": "http://www.w3.org/1999/xhtml", + "next": [Circular], + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, }, ], - "name": "style", + "name": "html", "namespace": "http://www.w3.org/1999/xhtml", "next": null, "parent": [Circular], - "prev": [Circular], - "type": "style", - "x-attribsNamespace": Object {}, - "x-attribsPrefix": Object {}, - }, - "parent": [Circular], - "prev": null, - "type": "tag", - "x-attribsNamespace": Object { - "class": undefined, - }, - "x-attribsPrefix": Object { - "class": undefined, - }, - }, - Node { - "attribs": Object {}, - "children": Array [ - Node { - "data": " - .avatar { - width: 1.875rem; - height: 1.875rem; - display: inline-block; - position: relative; - overflow: hidden; - border: 1px solid #eaeaea; - border-radius: 50%; - vertical-align: top; - background-color: #fff; - margin: 0 0 0 0; - } - - .avatar:first-child { - margin: 0; - } - - .avatar-img { - display: inline-block; - object-fit: cover; - width: 100%; - height: 100%; - border-radius: 50%; - } - - .avatar-text { - position: absolute; - left: 50%; - top: 50%; - font-size: 1em; - text-align: center; - transform: translate(-50%, -50%) scale(0.65); - white-space: nowrap; - user-select: none; - } - ", - "next": null, - "parent": [Circular], - "prev": null, - "type": "text", - }, - ], - "name": "style", - "namespace": "http://www.w3.org/1999/xhtml", - "next": null, - "parent": [Circular], - "prev": Node { - "attribs": Object { - "class": "avatar-text", - }, - "children": Array [], - "name": "span", - "namespace": "http://www.w3.org/1999/xhtml", - "next": [Circular], - "parent": [Circular], "prev": null, "type": "tag", - "x-attribsNamespace": Object { - "class": undefined, - }, - "x-attribsPrefix": Object { - "class": undefined, - }, + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, }, - "type": "style", - "x-attribsNamespace": Object {}, - "x-attribsPrefix": Object {}, - }, - ], - "name": "span", - "namespace": "http://www.w3.org/1999/xhtml", - "next": null, - "parent": Node { - "children": Array [ - [Circular], ], "name": "root", "next": null, "parent": null, "prev": null, "type": "root", + "x-mode": "quirks", }, - "prev": null, - "type": "tag", - "x-attribsNamespace": Object { - "class": undefined, - }, - "x-attribsPrefix": Object { - "class": undefined, + "_root": [Circular], + "length": 1, + "options": Object { + "decodeEntities": true, + "xml": false, }, }, - "_root": [Circular], "length": 1, "options": Object { "decodeEntities": true, @@ -371,7 +260,7 @@ initialize { `; exports[`Avatar should render text element 2`] = ` -initialize { +LoadedCheerio { "0": Node { "attribs": Object { "class": "avatar ", @@ -398,8 +287,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -407,26 +294,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -464,8 +352,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -473,26 +359,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -562,7 +449,83 @@ initialize { "class": undefined, }, }, - "_root": [Circular], + "_root": LoadedCheerio { + "0": Node { + "children": Array [ + Node { + "attribs": Object {}, + "children": Array [ + Node { + "attribs": Object {}, + "children": Array [], + "name": "head", + "namespace": "http://www.w3.org/1999/xhtml", + "next": Node { + "attribs": Object {}, + "children": Array [], + "name": "body", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": [Circular], + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + Node { + "attribs": Object {}, + "children": Array [], + "name": "body", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": Node { + "attribs": Object {}, + "children": Array [], + "name": "head", + "namespace": "http://www.w3.org/1999/xhtml", + "next": [Circular], + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + ], + "name": "html", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + ], + "name": "root", + "next": null, + "parent": null, + "prev": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": Object { + "decodeEntities": true, + "xml": false, + }, + }, "length": 1, "options": Object { "decodeEntities": true, @@ -572,7 +535,7 @@ initialize { `; exports[`Avatar should stacked when avatars are in a group 1`] = ` -initialize { +LoadedCheerio { "0": Node { "attribs": Object { "class": "avatar-group ", @@ -596,8 +559,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -605,26 +566,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -662,8 +624,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -671,26 +631,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -750,8 +711,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -759,26 +718,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -816,8 +776,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -825,26 +783,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -894,19 +853,21 @@ initialize { .avatar-group { display: flex; align-items: center; - height: auto; width: max-content; + height: auto; + padding: 0 0 0 0; + margin: 0 0 0 0; } .avatar-group :global(.avatar) { - margin-left: -0.625rem; + margin-left: -calc(0.625 * 16px); } .count { - font-size: 0.875rem; + font-size: calc(0.875 * 16px); display: inline-flex; align-items: center; - padding-left: 4pt; + padding-left: 5.5px; color: #333; } ", @@ -963,8 +924,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -972,26 +931,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -1029,8 +989,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -1038,26 +996,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -1107,19 +1066,21 @@ initialize { .avatar-group { display: flex; align-items: center; - height: auto; width: max-content; + height: auto; + padding: 0 0 0 0; + margin: 0 0 0 0; } .avatar-group :global(.avatar) { - margin-left: -0.625rem; + margin-left: -calc(0.625 * 16px); } .count { - font-size: 0.875rem; + font-size: calc(0.875 * 16px); display: inline-flex; align-items: center; - padding-left: 4pt; + padding-left: 5.5px; color: #333; } ", @@ -1157,8 +1118,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -1166,26 +1125,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -1223,8 +1183,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -1232,26 +1190,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -1320,19 +1279,21 @@ initialize { .avatar-group { display: flex; align-items: center; - height: auto; width: max-content; + height: auto; + padding: 0 0 0 0; + margin: 0 0 0 0; } .avatar-group :global(.avatar) { - margin-left: -0.625rem; + margin-left: -calc(0.625 * 16px); } .count { - font-size: 0.875rem; + font-size: calc(0.875 * 16px); display: inline-flex; align-items: center; - padding-left: 4pt; + padding-left: 5.5px; color: #333; } ", @@ -1364,8 +1325,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -1373,26 +1332,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -1430,8 +1390,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -1439,26 +1397,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -1520,8 +1479,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -1529,26 +1486,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -1586,8 +1544,6 @@ initialize { Node { "data": " .avatar { - width: 1.875rem; - height: 1.875rem; display: inline-block; position: relative; overflow: hidden; @@ -1595,26 +1551,27 @@ initialize { border-radius: 50%; vertical-align: top; background-color: #fff; + box-sizing: border-box; + width: calc(1.75 * 16px); + height: calc(1.75 * 16px); + padding: 0 0 0 0; margin: 0 0 0 0; } - .avatar:first-child { - margin: 0; - } - .avatar-img { display: inline-block; object-fit: cover; width: 100%; height: 100%; border-radius: 50%; + user-select: none; } .avatar-text { position: absolute; left: 50%; top: 50%; - font-size: 1em; + font-size: calc(1 * 16px); text-align: center; transform: translate(-50%, -50%) scale(0.65); white-space: nowrap; @@ -1702,7 +1659,83 @@ initialize { "class": undefined, }, }, - "_root": [Circular], + "_root": LoadedCheerio { + "0": Node { + "children": Array [ + Node { + "attribs": Object {}, + "children": Array [ + Node { + "attribs": Object {}, + "children": Array [], + "name": "head", + "namespace": "http://www.w3.org/1999/xhtml", + "next": Node { + "attribs": Object {}, + "children": Array [], + "name": "body", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": [Circular], + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + Node { + "attribs": Object {}, + "children": Array [], + "name": "body", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": Node { + "attribs": Object {}, + "children": Array [], + "name": "head", + "namespace": "http://www.w3.org/1999/xhtml", + "next": [Circular], + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + ], + "name": "html", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": [Circular], + "prev": null, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + ], + "name": "root", + "next": null, + "parent": null, + "prev": null, + "type": "root", + "x-mode": "quirks", + }, + "_root": [Circular], + "length": 1, + "options": Object { + "decodeEntities": true, + "xml": false, + }, + }, "length": 1, "options": Object { "decodeEntities": true, diff --git a/components/avatar/__tests__/index.test.tsx b/components/avatar/__tests__/index.test.tsx index d3140f9de..f7f3d4976 100644 --- a/components/avatar/__tests__/index.test.tsx +++ b/components/avatar/__tests__/index.test.tsx @@ -28,11 +28,6 @@ describe('Avatar', () => { expect(() => avatar.unmount()).not.toThrow() }) - it('should render component of a specified size', () => { - const avatar = render() - expect(avatar).toMatchSnapshot() - }) - it('group component should render all children', () => { const group = mount( @@ -55,8 +50,8 @@ describe('Avatar', () => { it('should show count in group', () => { const count = 20 - const group = shallow() + const group = render() const text = group.find('.count').text() - expect(text).toContain(count) + expect(text).toMatch(`${count}`) }) }) diff --git a/components/avatar/avatar-group.tsx b/components/avatar/avatar-group.tsx index 612c6e930..8b77dd99c 100644 --- a/components/avatar/avatar-group.tsx +++ b/components/avatar/avatar-group.tsx @@ -1,6 +1,6 @@ import React from 'react' import useTheme from '../use-theme' -import withDefaults from '../utils/with-defaults' +import useScaleable, { withScaleable } from '../use-scaleable' interface Props { count?: number @@ -12,14 +12,15 @@ const defaultProps = { } type NativeAttrs = Omit, keyof Props> -export type AvatarGroupProps = Props & typeof defaultProps & NativeAttrs +export type AvatarGroupProps = Props & NativeAttrs -const AvatarGroup: React.FC> = ({ +const AvatarGroupComponent: React.FC> = ({ count, className, children, -}) => { +}: AvatarGroupProps & typeof defaultProps) => { const theme = useTheme() + const { SCALES } = useScaleable() return (
@@ -29,19 +30,21 @@ const AvatarGroup: React.FC> = ({ .avatar-group { display: flex; align-items: center; - height: auto; - width: max-content; + width: ${SCALES.width(1, 'max-content')}; + height: ${SCALES.height(1, 'auto')}; + padding: ${SCALES.pt(0)} ${SCALES.pr(0)} ${SCALES.pb(0)} ${SCALES.pl(0)}; + margin: ${SCALES.mt(0)} ${SCALES.mr(0)} ${SCALES.mb(0)} ${SCALES.ml(0)}; } .avatar-group :global(.avatar) { - margin-left: -0.625rem; + margin-left: -${SCALES.ml(0.625)}; } .count { - font-size: 0.875rem; + font-size: ${SCALES.font(0.875)}; display: inline-flex; align-items: center; - padding-left: ${theme.layout.gapQuarter}; + padding-left: 5.5px; color: ${theme.palette.accents_7}; } `} @@ -49,4 +52,7 @@ const AvatarGroup: React.FC> = ({ ) } -export default withDefaults(AvatarGroup, defaultProps) +AvatarGroupComponent.defaultProps = defaultProps +AvatarGroupComponent.displayName = 'GeistAvatarGroup' +const AvatarGroup = withScaleable(AvatarGroupComponent) +export default AvatarGroup diff --git a/components/avatar/avatar.tsx b/components/avatar/avatar.tsx index 31bca70f5..6265b75cb 100644 --- a/components/avatar/avatar.tsx +++ b/components/avatar/avatar.tsx @@ -1,13 +1,11 @@ -import React, { useMemo } from 'react' -import { NormalSizes } from '../utils/prop-types' +import React from 'react' import useTheme from '../use-theme' -import AvatarGroup from './avatar-group' +import useScaleable, { withScaleable } from '../use-scaleable' interface Props { src?: string stacked?: boolean text?: string - size?: NormalSizes | number isSquare?: boolean className?: string } @@ -15,7 +13,6 @@ interface Props { const defaultProps = { stacked: false, text: '', - size: 'small' as NormalSizes | number, isSquare: false, className: '', } @@ -24,42 +21,32 @@ type NativeAttrs = Omit< Partial & React.HTMLAttributes>, keyof Props > -export type AvatarProps = Props & typeof defaultProps & NativeAttrs - -const getSize = (size: NormalSizes | number): string => { - const sizes: { [key in NormalSizes]: string } = { - mini: '1.25rem', - small: '1.875rem', - medium: '3.75rem', - large: '5.625rem', - } - if (typeof size === 'number') return `${size}px` - return sizes[size] -} +export type AvatarProps = Props & NativeAttrs const safeText = (text: string): string => { if (text.length <= 4) return text return text.slice(0, 3) } -const Avatar: React.FC = ({ +const AvatarComponent: React.FC = ({ src, stacked, text, - size, isSquare, className, ...props -}) => { +}: AvatarProps & typeof defaultProps) => { const theme = useTheme() + const { SCALES } = useScaleable() const showText = !src const radius = isSquare ? theme.layout.radius : '50%' - const marginLeft = stacked ? '-.625rem' : 0 - const width = useMemo(() => getSize(size), [size]) + const marginLeft = stacked ? SCALES.ml(-0.625) : SCALES.ml(0) return ( - {!showText && } + {!showText && ( + avatar + )} {showText && ( {safeText(text)} @@ -68,8 +55,6 @@ const Avatar: React.FC = ({ ) } -type MemoBadgeComponent

= React.NamedExoticComponent

& { - Anchor: typeof BadgeAnchor -} -type ComponentProps = Partial & - Omit & - NativeAttrs - -Badge.defaultProps = defaultProps - -export default React.memo(Badge) as MemoBadgeComponent +BadgeComponent.defaultProps = defaultProps +BadgeComponent.displayName = 'GeistBadge' +const Badge = withScaleable(BadgeComponent) +export default Badge diff --git a/components/badge/index.ts b/components/badge/index.ts index 191d73348..6061e3ac2 100644 --- a/components/badge/index.ts +++ b/components/badge/index.ts @@ -1,6 +1,11 @@ import Badge from './badge' import BadgeAnchor from './badge-anchor' -Badge.Anchor = BadgeAnchor +export type BadgeComponentType = typeof Badge & { + Anchor: typeof BadgeAnchor +} +;(Badge as BadgeComponentType).Anchor = BadgeAnchor -export default Badge +export type { BadgeProps, BadgeTypes } from './badge' +export type { BadgeAnchorProps, BadgeAnchorPlacement } from './badge-anchor' +export default Badge as BadgeComponentType diff --git a/components/breadcrumbs/__tests__/__snapshots__/breadcrumbs.test.tsx.snap b/components/breadcrumbs/__tests__/__snapshots__/breadcrumbs.test.tsx.snap index 58a621cc6..3385841e8 100644 --- a/components/breadcrumbs/__tests__/__snapshots__/breadcrumbs.test.tsx.snap +++ b/components/breadcrumbs/__tests__/__snapshots__/breadcrumbs.test.tsx.snap @@ -4,21 +4,26 @@ exports[`Breadcrumbs should redefined all separators 1`] = ` "

) } -const MemoBreadcrumbsSeparator = React.memo(BreadcrumbsSeparator) - -export default withDefaults(MemoBreadcrumbsSeparator, defaultProps) +Separator.defaultProps = defaultProps +Separator.displayName = 'GeistBreadcrumbsSeparator' +const BreadcrumbsSeparator = withScaleable(Separator) +export default BreadcrumbsSeparator diff --git a/components/breadcrumbs/breadcrumbs.tsx b/components/breadcrumbs/breadcrumbs.tsx index 453c0dcd0..477bb4bcc 100644 --- a/components/breadcrumbs/breadcrumbs.tsx +++ b/components/breadcrumbs/breadcrumbs.tsx @@ -1,43 +1,29 @@ import React, { ReactNode, useMemo } from 'react' import useTheme from '../use-theme' -import BreadcrumbsItem from './breadcrumbs-item' import BreadcrumbsSeparator from './breadcrumbs-separator' import { addColorAlpha } from '../utils/color' -import { NormalSizes } from '../utils/prop-types' +import useScaleable, { withScaleable } from '../use-scaleable' interface Props { - size: NormalSizes separator?: string | ReactNode className?: string } const defaultProps = { - size: 'medium' as NormalSizes, separator: '/', className: '', } type NativeAttrs = Omit, keyof Props> -export type BreadcrumbsProps = Props & typeof defaultProps & NativeAttrs +export type BreadcrumbsProps = Props & NativeAttrs -const getSize = (size: NormalSizes) => { - const sizes: { [key in NormalSizes]: string } = { - mini: '.75rem', - small: '.875rem', - medium: '1rem', - large: '1.125rem', - } - return sizes[size] -} - -const Breadcrumbs: React.FC> = ({ - size, +const BreadcrumbsComponent: React.FC> = ({ separator, children, className, -}) => { +}: BreadcrumbsProps & typeof defaultProps) => { const theme = useTheme() - const fontSize = useMemo(() => getSize(size), [size]) + const { SCALES } = useScaleable() const hoverColor = useMemo(() => { return addColorAlpha(theme.palette.link, 0.85) }, [theme.palette.link]) @@ -65,14 +51,16 @@ const Breadcrumbs: React.FC> = ({ {withSeparatorChildren}
footer
@@ -41,6 +42,7 @@ const CardContent: React.FC> = ({ ) } -const MemoCardContent = React.memo(CardContent) - -export default withDefaults(MemoCardContent, defaultProps) +CardContentComponent.defaultProps = defaultProps +CardContentComponent.displayName = 'GeistCardContent' +const CardContent = withScaleable(CardContentComponent) +export default CardContent diff --git a/components/card/card-footer.tsx b/components/card/card-footer.tsx index 7a616a1c7..604a49e65 100644 --- a/components/card/card-footer.tsx +++ b/components/card/card-footer.tsx @@ -1,6 +1,6 @@ import React from 'react' import useTheme from '../use-theme' -import withDefaults from '../utils/with-defaults' +import useScaleable, { withScaleable } from '../use-scaleable' interface Props { disableAutoMargin?: boolean @@ -13,15 +13,16 @@ const defaultProps = { } type NativeAttrs = Omit, keyof Props> -export type CardFooterProps = Props & typeof defaultProps & NativeAttrs +export type CardFooterProps = Props & NativeAttrs -const CardFooter: React.FC> = ({ +const CardFooterComponent: React.FC> = ({ children, className, disableAutoMargin, ...props -}) => { +}: CardFooterProps & typeof defaultProps) => { const theme = useTheme() + const { SCALES } = useScaleable() return (