├── .gitignore ├── .prettierrc.mjs ├── .storybook ├── main.ts ├── preview-head.html └── preview.tsx ├── .yarn └── releases │ └── yarn-4.9.1.cjs ├── .yarnrc.yml ├── LICENCE ├── README.md ├── components ├── CategoryHeader │ ├── CategoryHeader.module.css │ └── CategoryHeader.tsx ├── CategoryPage │ └── CategoryPage.tsx ├── ChangelogPage │ ├── ChangelogPage.module.css │ └── ChangelogPage.tsx ├── ComponentCanvas │ ├── CanvasHeader │ │ ├── CanvasHeader.module.css │ │ └── CanvasHeader.tsx │ ├── ComponentCanvas.module.css │ └── ComponentCanvas.tsx ├── ComponentPage │ └── ComponentPage.tsx ├── ComponentPreview │ └── ComponentPreview.tsx ├── ComponentPreviewControls │ └── ComponentPreviewControls.tsx ├── GaScript │ ├── GaScript.tsx │ └── index.ts ├── HomePage │ ├── Banner │ │ ├── Banner.module.css │ │ ├── Banner.tsx │ │ ├── banner.webp │ │ └── data.ts │ ├── CategoriesList │ │ ├── CategoriesList.module.css │ │ └── CategoriesList.tsx │ ├── CategoryCard │ │ ├── CategoryCard.module.css │ │ └── CategoryCard.tsx │ └── HomePage.tsx ├── HotKeysHandler │ ├── HotKeysHandler.tsx │ └── index.ts ├── PageHead │ ├── PageHead.tsx │ └── index.ts ├── Search │ ├── Search.tsx │ └── index.ts ├── Shell │ ├── Shell.module.css │ ├── Shell.tsx │ └── index.ts └── StoryWrapper │ └── StoryWrapper.tsx ├── data ├── categories.ts ├── components.ts ├── images │ ├── authentication-dark.svg │ ├── authentication-light.svg │ ├── banners-dark.svg │ ├── banners-light.svg │ ├── buttons-dark.svg │ ├── buttons-light.svg │ ├── cards-dark.svg │ ├── cards-light.svg │ ├── carousels-dark.svg │ ├── carousels-light.svg │ ├── color-scheme-dark.svg │ ├── color-scheme-light.svg │ ├── comments-dark.svg │ ├── comments-light.svg │ ├── contact-dark.svg │ ├── contact-light.svg │ ├── dnd-dark.svg │ ├── dnd-light.svg │ ├── dropzones-dark.svg │ ├── dropzones-light.svg │ ├── error-pages-dark.svg │ ├── error-pages-light.svg │ ├── faq-dark.svg │ ├── faq-light.svg │ ├── features-dark.svg │ ├── features-light.svg │ ├── footers-dark.svg │ ├── footers-light.svg │ ├── grids-dark.svg │ ├── grids-light.svg │ ├── headers-dark.svg │ ├── headers-light.svg │ ├── hero-dark.svg │ ├── hero-light.svg │ ├── index.ts │ ├── inputs-dark.svg │ ├── inputs-light.svg │ ├── navbars-dark.svg │ ├── navbars-light.svg │ ├── sliders-dark.svg │ ├── sliders-light.svg │ ├── stats-dark.svg │ ├── stats-light.svg │ ├── tables-dark.svg │ ├── tables-light.svg │ ├── toc-dark.svg │ ├── toc-light.svg │ ├── users-dark.svg │ └── users-light.svg ├── index.ts └── types.ts ├── eslint.config.mjs ├── lib ├── ActionToggle │ ├── ActionToggle.module.css │ ├── ActionToggle.story.tsx │ ├── ActionToggle.tsx │ └── attributes.json ├── ActionsGrid │ ├── ActionsGrid.module.css │ ├── ActionsGrid.story.tsx │ ├── ActionsGrid.tsx │ └── attributes.json ├── ArticleCard │ ├── ArticleCard.module.css │ ├── ArticleCard.story.tsx │ ├── ArticleCard.tsx │ └── attributes.json ├── ArticleCardFooter │ ├── ArticleCardFooter.module.css │ ├── ArticleCardFooter.story.tsx │ ├── ArticleCardFooter.tsx │ └── attributes.json ├── ArticleCardImage │ ├── ArticleCardImage.module.css │ ├── ArticleCardImage.story.tsx │ ├── ArticleCardImage.tsx │ └── attributes.json ├── ArticleCardVertical │ ├── ArticleCardVertical.module.css │ ├── ArticleCardVertical.story.tsx │ ├── ArticleCardVertical.tsx │ └── attributes.json ├── ArticlesCardsGrid │ ├── ArticlesCardsGrid.module.css │ ├── ArticlesCardsGrid.story.tsx │ ├── ArticlesCardsGrid.tsx │ └── attributes.json ├── AuthenticationForm │ ├── AuthenticationForm.story.tsx │ ├── AuthenticationForm.tsx │ ├── GoogleButton.tsx │ ├── TwitterButton.tsx │ └── attributes.json ├── AuthenticationImage │ ├── AuthenticationImage.module.css │ ├── AuthenticationImage.story.tsx │ ├── AuthenticationImage.tsx │ └── attributes.json ├── AuthenticationTitle │ ├── AuthenticationTitle.module.css │ ├── AuthenticationTitle.story.tsx │ ├── AuthenticationTitle.tsx │ └── attributes.json ├── AutocompleteLoading │ ├── AutocompleteLoading.story.tsx │ ├── AutocompleteLoading.tsx │ └── attributes.json ├── BadgeCard │ ├── BadgeCard.module.css │ ├── BadgeCard.story.tsx │ ├── BadgeCard.tsx │ └── attributes.json ├── ButtonCopy │ ├── ButtonCopy.story.tsx │ ├── ButtonCopy.tsx │ └── attributes.json ├── ButtonMenu │ ├── ButtonMenu.story.tsx │ ├── ButtonMenu.tsx │ └── attributes.json ├── ButtonProgress │ ├── ButtonProgress.module.css │ ├── ButtonProgress.story.tsx │ ├── ButtonProgress.tsx │ └── attributes.json ├── CardGradient │ ├── CardGradient.module.css │ ├── CardGradient.story.tsx │ ├── CardGradient.tsx │ └── attributes.json ├── CardWithStats │ ├── CardWithStats.module.css │ ├── CardWithStats.story.tsx │ ├── CardWithStats.tsx │ └── attributes.json ├── CardsCarousel │ ├── CardsCarousel.module.css │ ├── CardsCarousel.story.tsx │ ├── CardsCarousel.tsx │ └── attributes.json ├── CarouselCard │ ├── CarouselCard.module.css │ ├── CarouselCard.story.tsx │ ├── CarouselCard.tsx │ └── attributes.json ├── CheckboxCard │ ├── CheckboxCard.module.css │ ├── CheckboxCard.story.tsx │ ├── CheckboxCard.tsx │ └── attributes.json ├── CommentHtml │ ├── CommentHtml.module.css │ ├── CommentHtml.story.tsx │ ├── CommentHtml.tsx │ └── attributes.json ├── CommentSimple │ ├── CommentSimple.story.tsx │ ├── CommentSimple.tsx │ └── attributes.json ├── ContactUs │ ├── ContactIcons.module.css │ ├── ContactIcons.tsx │ ├── ContactUs.module.css │ ├── ContactUs.story.tsx │ ├── ContactUs.tsx │ └── attributes.json ├── ContainedInputs │ ├── ContainedInput.module.css │ ├── ContainedInputs.story.tsx │ ├── ContainedInputs.tsx │ └── attributes.json ├── CookiesBanner │ ├── CookiesBanner.story.tsx │ ├── CookiesBanner.tsx │ └── attributes.json ├── CurrencyInput │ ├── CurrencyInput.story.tsx │ ├── CurrencyInput.tsx │ └── attributes.json ├── CustomSwitch │ ├── CustomSwitch.module.css │ ├── CustomSwitch.story.tsx │ ├── CustomSwitch.tsx │ └── attributes.json ├── DndList │ ├── DndList.module.css │ ├── DndList.story.tsx │ ├── DndList.tsx │ └── attributes.json ├── DndListHandle │ ├── DndListHandle.module.css │ ├── DndListHandle.story.tsx │ ├── DndListHandle.tsx │ └── attributes.json ├── DndTable │ ├── DndTable.module.css │ ├── DndTable.story.tsx │ ├── DndTable.tsx │ └── attributes.json ├── DoubleHeader │ ├── DoubleHeader.module.css │ ├── DoubleHeader.story.tsx │ ├── DoubleHeader.tsx │ └── attributes.json ├── DoubleNavbar │ ├── DoubleNavbar.module.css │ ├── DoubleNavbar.story.tsx │ ├── DoubleNavbar.tsx │ └── attributes.json ├── DropzoneButton │ ├── DropzoneButton.module.css │ ├── DropzoneButton.story.tsx │ ├── DropzoneButton.tsx │ └── attributes.json ├── EmailBanner │ ├── EmailBanner.module.css │ ├── EmailBanner.story.tsx │ ├── EmailBanner.tsx │ ├── attributes.json │ └── image.svg ├── FaqSimple │ ├── FaqSimple.module.css │ ├── FaqSimple.story.tsx │ ├── FaqSimple.tsx │ └── attributes.json ├── FaqWithBg │ ├── FaqWithBg.module.css │ ├── FaqWithBg.story.tsx │ ├── FaqWithBg.tsx │ └── attributes.json ├── FaqWithHeader │ ├── ContactIcons.module.css │ ├── ContactIcons.tsx │ ├── FaqWithHeader.module.css │ ├── FaqWithHeader.story.tsx │ ├── FaqWithHeader.tsx │ └── attributes.json ├── FaqWithImage │ ├── FaqWithImage.module.css │ ├── FaqWithImage.story.tsx │ ├── FaqWithImage.tsx │ ├── attributes.json │ └── image.svg ├── FeaturesAsymmetrical │ ├── FeaturesAsymmetrical.module.css │ ├── FeaturesAsymmetrical.story.tsx │ ├── FeaturesAsymmetrical.tsx │ └── attributes.json ├── FeaturesCard │ ├── FeaturesCard.module.css │ ├── FeaturesCard.story.tsx │ ├── FeaturesCard.tsx │ └── attributes.json ├── FeaturesCards │ ├── FeaturesCards.module.css │ ├── FeaturesCards.story.tsx │ ├── FeaturesCards.tsx │ └── attributes.json ├── FeaturesGrid │ ├── FeaturesGrid.module.css │ ├── FeaturesGrid.story.tsx │ ├── FeaturesGrid.tsx │ └── attributes.json ├── FeaturesImages │ ├── FeaturesImages.module.css │ ├── FeaturesImages.story.tsx │ ├── FeaturesImages.tsx │ ├── attributes.json │ └── images │ │ ├── accountants.svg │ │ ├── auditors.svg │ │ ├── index.ts │ │ ├── lawyers.svg │ │ └── others.svg ├── FeaturesTitle │ ├── FeaturesTitle.module.css │ ├── FeaturesTitle.story.tsx │ ├── FeaturesTitle.tsx │ └── attributes.json ├── FloatingLabelInput │ ├── FloatingLabelInput.module.css │ ├── FloatingLabelInput.story.tsx │ ├── FloatingLabelInput.tsx │ └── attributes.json ├── FooterCentered │ ├── FooterCentered.module.css │ ├── FooterCentered.story.tsx │ ├── FooterCentered.tsx │ └── attributes.json ├── FooterLinks │ ├── FooterLinks.module.css │ ├── FooterLinks.story.tsx │ ├── FooterLinks.tsx │ └── attributes.json ├── FooterSimple │ ├── FooterSimple.module.css │ ├── FooterSimple.story.tsx │ ├── FooterSimple.tsx │ └── attributes.json ├── FooterSocial │ ├── FooterSocial.module.css │ ├── FooterSocial.story.tsx │ ├── FooterSocial.tsx │ └── attributes.json ├── ForgotPassword │ ├── ForgotPassword.module.css │ ├── ForgotPassword.story.tsx │ ├── ForgotPassword.tsx │ └── attributes.json ├── ForgotPasswordInput │ ├── ForgotPasswordInput.story.tsx │ ├── ForgotPasswordInput.tsx │ └── attributes.json ├── GetInTouch │ ├── ContactIcons.module.css │ ├── ContactIcons.tsx │ ├── GetInTouch.module.css │ ├── GetInTouch.story.tsx │ ├── GetInTouch.tsx │ ├── attributes.json │ └── bg.svg ├── GetInTouchSimple │ ├── GetInTouchSimple.story.tsx │ ├── GetInTouchSimple.tsx │ └── attributes.json ├── GradientSegmentedControl │ ├── GradientSegmentedControl.module.css │ ├── GradientSegmentedControl.story.tsx │ ├── GradientSegmentedControl.tsx │ └── attributes.json ├── GridAsymmetrical │ ├── GridAsymmetrical.story.tsx │ ├── GridAsymmetrical.tsx │ └── attributes.json ├── HeaderMegaMenu │ ├── HeaderMegaMenu.module.css │ ├── HeaderMegaMenu.story.tsx │ ├── HeaderMegaMenu.tsx │ └── attributes.json ├── HeaderMenu │ ├── HeaderMenu.module.css │ ├── HeaderMenu.story.tsx │ ├── HeaderMenu.tsx │ └── attributes.json ├── HeaderSearch │ ├── HeaderSearch.module.css │ ├── HeaderSearch.story.tsx │ ├── HeaderSearch.tsx │ └── attributes.json ├── HeaderSimple │ ├── HeaderSimple.module.css │ ├── HeaderSimple.story.tsx │ ├── HeaderSimple.tsx │ └── attributes.json ├── HeaderTabs │ ├── HeaderTabs.module.css │ ├── HeaderTabs.story.tsx │ ├── HeaderTabs.tsx │ └── attributes.json ├── HeroBullets │ ├── HeroBullets.module.css │ ├── HeroBullets.story.tsx │ ├── HeroBullets.tsx │ ├── attributes.json │ └── image.svg ├── HeroContentLeft │ ├── HeroContentLeft.module.css │ ├── HeroContentLeft.story.tsx │ ├── HeroContentLeft.tsx │ └── attributes.json ├── HeroImageBackground │ ├── HeroImageBackground.module.css │ ├── HeroImageBackground.story.tsx │ ├── HeroImageBackground.tsx │ └── attributes.json ├── HeroImageRight │ ├── HeroImageRight.module.css │ ├── HeroImageRight.story.tsx │ ├── HeroImageRight.tsx │ └── attributes.json ├── HeroText │ ├── Dots.tsx │ ├── HeroText.module.css │ ├── HeroText.story.tsx │ ├── HeroText.tsx │ └── attributes.json ├── HeroTitle │ ├── HeroTitle.module.css │ ├── HeroTitle.story.tsx │ ├── HeroTitle.tsx │ └── attributes.json ├── ImageActionBanner │ ├── ImageActionBanner.module.css │ ├── ImageActionBanner.story.tsx │ ├── ImageActionBanner.tsx │ └── attributes.json ├── ImageCard │ ├── ImageCard.module.css │ ├── ImageCard.story.tsx │ ├── ImageCard.tsx │ └── attributes.json ├── ImageCheckboxes │ ├── ImageCheckboxes.module.css │ ├── ImageCheckboxes.story.tsx │ ├── ImageCheckboxes.tsx │ ├── attributes.json │ └── icons │ │ ├── city.png │ │ ├── index.ts │ │ ├── mountain.png │ │ ├── sea.png │ │ └── winter.png ├── InputTooltip │ ├── InputTooltip.story.tsx │ ├── InputTooltip.tsx │ └── attributes.json ├── InputValidation │ ├── InputValidation.module.css │ ├── InputValidation.story.tsx │ ├── InputValidation.tsx │ └── attributes.json ├── InputWithButton │ ├── InputWithButton.story.tsx │ ├── InputWithButton.tsx │ └── attributes.json ├── LanguagePicker │ ├── LanguagePicker.module.css │ ├── LanguagePicker.story.tsx │ ├── LanguagePicker.tsx │ ├── attributes.json │ └── images │ │ ├── english.png │ │ ├── french.png │ │ ├── german.png │ │ ├── index.ts │ │ ├── italian.png │ │ └── polish.png ├── LeadGrid │ ├── LeadGrid.story.tsx │ ├── LeadGrid.tsx │ └── attributes.json ├── NavbarLinksGroup │ ├── NavbarLinksGroup.module.css │ ├── NavbarLinksGroup.story.tsx │ ├── NavbarLinksGroup.tsx │ └── attributes.json ├── NavbarMinimal │ ├── NavbarMinimal.module.css │ ├── NavbarMinimal.story.tsx │ ├── NavbarMinimal.tsx │ └── attributes.json ├── NavbarMinimalColored │ ├── NavbarMinimalColored.module.css │ ├── NavbarMinimalColored.story.tsx │ ├── NavbarMinimalColored.tsx │ └── attributes.json ├── NavbarNested │ ├── Logo.tsx │ ├── NavbarNested.module.css │ ├── NavbarNested.story.tsx │ ├── NavbarNested.tsx │ └── attributes.json ├── NavbarSearch │ ├── NavbarSearch.module.css │ ├── NavbarSearch.story.tsx │ ├── NavbarSearch.tsx │ └── attributes.json ├── NavbarSegmented │ ├── NavbarSegmented.module.css │ ├── NavbarSegmented.story.tsx │ ├── NavbarSegmented.tsx │ └── attributes.json ├── NavbarSimple │ ├── NavbarSimple.module.css │ ├── NavbarSimple.story.tsx │ ├── NavbarSimple.tsx │ └── attributes.json ├── NavbarSimpleColored │ ├── NavbarSimpleColored.module.css │ ├── NavbarSimpleColored.story.tsx │ ├── NavbarSimpleColored.tsx │ └── attributes.json ├── NotFoundImage │ ├── NotFoundImage.module.css │ ├── NotFoundImage.story.tsx │ ├── NotFoundImage.tsx │ ├── attributes.json │ └── image.svg ├── NotFoundTitle │ ├── NotFoundTitle.module.css │ ├── NotFoundTitle.story.tsx │ ├── NotFoundTitle.tsx │ └── attributes.json ├── NothingFoundBackground │ ├── Illustration.tsx │ ├── NothingFoundBackground.module.css │ ├── NothingFoundBackground.story.tsx │ ├── NothingFoundBackground.tsx │ └── attributes.json ├── PasswordStrength │ ├── PasswordStrength.story.tsx │ ├── PasswordStrength.tsx │ └── attributes.json ├── ProgressCard │ ├── ProgressCard.story.tsx │ ├── ProgressCard.tsx │ └── attributes.json ├── ProgressCardColored │ ├── ProgressCardColored.module.css │ ├── ProgressCardColored.story.tsx │ ├── ProgressCardColored.tsx │ └── attributes.json ├── ServerError │ ├── ServerError.module.css │ ├── ServerError.story.tsx │ ├── ServerError.tsx │ └── attributes.json ├── ServerOverload │ ├── Illustration.tsx │ ├── ServerOverload.module.css │ ├── ServerOverload.story.tsx │ ├── ServerOverload.tsx │ └── attributes.json ├── SliderHover │ ├── SliderHover.story.tsx │ ├── SliderHover.tsx │ └── attributes.json ├── SliderIcon │ ├── SliderIcon.story.tsx │ ├── SliderIcon.tsx │ └── attributes.json ├── SliderInput │ ├── SliderInput.module.css │ ├── SliderInput.story.tsx │ ├── SliderInput.tsx │ └── attributes.json ├── SliderLabel │ ├── SliderLabel.module.css │ ├── SliderLabel.story.tsx │ ├── SliderLabel.tsx │ └── attributes.json ├── SliderMarks │ ├── SliderMarks.module.css │ ├── SliderMarks.story.tsx │ ├── SliderMarks.tsx │ └── attributes.json ├── SliderWhite │ ├── SliderWhite.module.css │ ├── SliderWhite.story.tsx │ ├── SliderWhite.tsx │ └── attributes.json ├── SocialButtons │ ├── FacebookIcon.tsx │ ├── GoogleIcon.tsx │ ├── SocialButtons.module.css │ ├── SocialButtons.story.tsx │ ├── SocialButtons.tsx │ └── attributes.json ├── SplitButton │ ├── SplitButton.module.css │ ├── SplitButton.story.tsx │ ├── SplitButton.tsx │ └── attributes.json ├── StatsCard │ ├── StatsCard.module.css │ ├── StatsCard.story.tsx │ ├── StatsCard.tsx │ └── attributes.json ├── StatsControls │ ├── StatsControls.module.css │ ├── StatsControls.story.tsx │ ├── StatsControls.tsx │ └── attributes.json ├── StatsGrid │ ├── StatsGrid.module.css │ ├── StatsGrid.story.tsx │ ├── StatsGrid.tsx │ └── attributes.json ├── StatsGridIcons │ ├── StatsGridIcons.module.css │ ├── StatsGridIcons.story.tsx │ ├── StatsGridIcons.tsx │ └── attributes.json ├── StatsGroup │ ├── StatsGroup.module.css │ ├── StatsGroup.story.tsx │ ├── StatsGroup.tsx │ └── attributes.json ├── StatsRing │ ├── StatsRing.story.tsx │ ├── StatsRing.tsx │ └── attributes.json ├── StatsRingCard │ ├── StatsRingCard.module.css │ ├── StatsRingCard.story.tsx │ ├── StatsRingCard.tsx │ └── attributes.json ├── StatsSegments │ ├── StatsSegments.module.css │ ├── StatsSegments.story.tsx │ ├── StatsSegments.tsx │ └── attributes.json ├── Subgrid │ ├── Subgrid.story.tsx │ ├── Subgrid.tsx │ └── attributes.json ├── SwitchesCard │ ├── SwitchesCard.module.css │ ├── SwitchesCard.story.tsx │ ├── SwitchesCard.tsx │ └── attributes.json ├── TableOfContents │ ├── TableOfContents.module.css │ ├── TableOfContents.story.tsx │ ├── TableOfContents.tsx │ └── attributes.json ├── TableOfContentsFloating │ ├── TableOfContentsFloating.module.css │ ├── TableOfContentsFloating.story.tsx │ ├── TableOfContentsFloating.tsx │ └── attributes.json ├── TableReviews │ ├── TableReviews.module.css │ ├── TableReviews.story.tsx │ ├── TableReviews.tsx │ └── attributes.json ├── TableScrollArea │ ├── TableScrollArea.module.css │ ├── TableScrollArea.story.tsx │ ├── TableScrollArea.tsx │ └── attributes.json ├── TableSelection │ ├── TableSelection.module.css │ ├── TableSelection.story.tsx │ ├── TableSelection.tsx │ └── attributes.json ├── TableSort │ ├── TableSort.module.css │ ├── TableSort.story.tsx │ ├── TableSort.tsx │ └── attributes.json ├── TaskCard │ ├── TaskCard.story.tsx │ ├── TaskCard.tsx │ └── attributes.json ├── UserButton │ ├── UserButton.module.css │ ├── UserButton.story.tsx │ ├── UserButton.tsx │ └── attributes.json ├── UserCardImage │ ├── UserCardImage.module.css │ ├── UserCardImage.story.tsx │ ├── UserCardImage.tsx │ └── attributes.json ├── UserInfoAction │ ├── UserInfoAction.story.tsx │ ├── UserInfoAction.tsx │ └── attributes.json ├── UserInfoIcons │ ├── UserInfoIcons.module.css │ ├── UserInfoIcons.story.tsx │ ├── UserInfoIcons.tsx │ └── attributes.json ├── UserMenu │ ├── UserMenu.story.tsx │ ├── UserMenu.tsx │ └── attributes.json ├── UsersRolesTable │ ├── UsersRolesTable.story.tsx │ ├── UsersRolesTable.tsx │ └── attributes.json ├── UsersStack │ ├── UsersStack.story.tsx │ ├── UsersStack.tsx │ └── attributes.json ├── UsersTable │ ├── UsersTable.story.tsx │ ├── UsersTable.tsx │ └── attributes.json └── index.ts ├── next-env.d.ts ├── next.config.mjs ├── package.json ├── pages ├── _app.tsx ├── _document.tsx ├── category │ └── [category].tsx ├── changelog │ └── [changelog].tsx ├── component │ └── [component].tsx └── index.tsx ├── postcss.config.cjs ├── public └── favicon.svg ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | ## yarn 34 | .yarn-integrity 35 | .yarn/cache 36 | .yarn/unplugged 37 | .yarn/build-state.yml 38 | .yarn/install-state.gz 39 | .pnp.* 40 | 41 | # vercel 42 | .vercel 43 | *.tsbuildinfo 44 | 45 | # storybook 46 | storybook-static -------------------------------------------------------------------------------- /.prettierrc.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import("@ianvs/prettier-plugin-sort-imports").PrettierConfig} */ 2 | const config = { 3 | printWidth: 100, 4 | singleQuote: true, 5 | trailingComma: 'es5', 6 | plugins: ['@ianvs/prettier-plugin-sort-imports'], 7 | importOrder: [ 8 | '.*styles.css#39;, 9 | '', 10 | 'dayjs', 11 | '^react#39;, 12 | '^next#39;, 13 | '^next/.*#39;, 14 | '<BUILTIN_MODULES>', 15 | '<THIRD_PARTY_MODULES>', 16 | '^@mantine/(.*)#39;, 17 | '^@mantinex/(.*)#39;, 18 | '^@mantine-tests/(.*)#39;, 19 | '^@docs/(.*)#39;, 20 | '^@/.*#39;, 21 | '^../(?!.*.css$).*#39;, 22 | '^./(?!.*.css$).*#39;, 23 | '\\.css#39;, 24 | ], 25 | overrides: [ 26 | { 27 | files: '*.mdx', 28 | options: { 29 | printWidth: 70, 30 | }, 31 | }, 32 | ], 33 | }; 34 | 35 | export default config; 36 | -------------------------------------------------------------------------------- /.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from '@storybook/nextjs'; 2 | 3 | const config: StorybookConfig = { 4 | stories: ['../lib/**/*.(stories|story).@(js|jsx|ts|tsx)'], 5 | addons: ['storybook-dark-mode', '@storybook/addon-styling-webpack'], 6 | framework: { 7 | name: '@storybook/nextjs', 8 | options: {}, 9 | }, 10 | }; 11 | export default config; 12 | -------------------------------------------------------------------------------- /.storybook/preview-head.html: -------------------------------------------------------------------------------- 1 | <link rel="preconnect" href="https://fonts.googleapis.com" /> 2 | <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> 3 | <link 4 | href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" 5 | rel="stylesheet" 6 | /> 7 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | yarnPath: .yarn/releases/yarn-4.9.1.cjs 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mantine UI 2 | 3 | [Mantine UI](https://ui.mantine.dev/) is a set of more than 120 responsive components built with [Mantine](https://mantine.dev/). All components support dark/light color scheme and Mantine theme customizations. Mantine UI is free for everyone. 4 | 5 | ## Contributing 6 | 7 | Mantine UI is an open source project with MIT license – you can browse source code and use components 8 | in your applications without any limitations. Although the project is open source, **we do not accept 9 | any contributions to the codebase of Mantine UI (unless maintainers asked you to send a PR).** You can contribute to the [Mantine library](https://github.com/mantinedev/mantine) codebase instead. 10 | 11 | ## License 12 | 13 | MIT 14 | -------------------------------------------------------------------------------- /components/CategoryHeader/CategoryHeader.module.css: -------------------------------------------------------------------------------- 1 | .title { 2 | font-family: Outfit, var(--mantine-font-family); 3 | font-weight: 500; 4 | margin-bottom: var(--mantine-spacing-md); 5 | margin-top: var(--mantine-spacing-md); 6 | font-size: 44px; 7 | color: var(--mantine-color-bright); 8 | } 9 | -------------------------------------------------------------------------------- /components/CategoryHeader/CategoryHeader.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | import { IconArrowLeft } from '@tabler/icons-react'; 3 | import { Anchor, Box, Center, Title } from '@mantine/core'; 4 | import { Category } from '../../data'; 5 | import classes from './CategoryHeader.module.css'; 6 | 7 | interface CategoryHeaderProps { 8 | category: Category; 9 | } 10 | 11 | export function CategoryHeader({ category }: CategoryHeaderProps) { 12 | return ( 13 | <> 14 | <Anchor component={Link} href="/#main"> 15 | <Center inline> 16 | <IconArrowLeft size={14} /> 17 | <Box component="span" ml={5}> 18 | Back to all categories 19 | </Box> 20 | </Center> 21 | </Anchor> 22 | 23 | <Title className={classes.title}>{category.name}</Title> 24 | </> 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /components/ChangelogPage/ChangelogPage.module.css: -------------------------------------------------------------------------------- 1 | .title { 2 | font-family: Outfit, var(--mantine-font-family); 3 | 4 | @media (max-width: em(500px)) { 5 | font-size: 26px; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /components/ComponentPreview/ComponentPreview.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from '@mantine/core'; 2 | import { CanvasAttributes } from '../../data'; 3 | 4 | interface ComponentPreviewProps { 5 | children: React.ReactNode; 6 | canvas: CanvasAttributes['canvas']; 7 | withSpacing?: boolean; 8 | } 9 | 10 | export function ComponentPreview({ children, canvas, withSpacing = false }: ComponentPreviewProps) { 11 | return ( 12 | <Box 13 | pt={canvas?.maxWidth && withSpacing ? 40 : 0} 14 | maw={canvas?.maxWidth ? canvas.maxWidth : '100%'} 15 | ml={canvas?.center ? 'auto' : 'unset'} 16 | mr={canvas?.center ? 'auto' : 'unset'} 17 | > 18 | {children} 19 | </Box> 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /components/ComponentPreviewControls/ComponentPreviewControls.tsx: -------------------------------------------------------------------------------- 1 | import { Affix } from '@mantine/core'; 2 | import { CanvasHeader, CanvasHeaderProps } from '../ComponentCanvas/CanvasHeader/CanvasHeader'; 3 | 4 | export function ComponentPreviewControls(props: CanvasHeaderProps) { 5 | return ( 6 | <Affix position={{ bottom: 0, left: 0, right: 0 }} zIndex={1}> 7 | <CanvasHeader {...props} excludeExternal style={{ borderBottom: 0 }} /> 8 | </Affix> 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /components/GaScript/GaScript.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Script from 'next/script'; 3 | 4 | const gaScript = ` 5 | window.dataLayer = window.dataLayer || []; 6 | function gtag(){dataLayer.push(arguments);} 7 | gtag('js', new Date()); 8 | 9 | gtag('config', 'G-NGWJJB04JB'); 10 | `; 11 | 12 | export function GaScript() { 13 | return ( 14 | <> 15 | <Script 16 | strategy="afterInteractive" 17 | src="https://www.googletagmanager.com/gtag/js?id=G-NGWJJB04JB" 18 | /> 19 | <Script id="ga" strategy="afterInteractive"> 20 | {gaScript} 21 | </Script> 22 | </> 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /components/GaScript/index.ts: -------------------------------------------------------------------------------- 1 | export { GaScript } from './GaScript'; 2 | -------------------------------------------------------------------------------- /components/HomePage/Banner/banner.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mantinedev/ui.mantine.dev/620ed0fa88be1e484bddc711af6f0903c037f04e/components/HomePage/Banner/banner.webp -------------------------------------------------------------------------------- /components/HomePage/Banner/data.ts: -------------------------------------------------------------------------------- 1 | import { IconFlame, IconLicense, IconMoonStars } from '@tabler/icons-react'; 2 | 3 | export default [ 4 | { 5 | icon: IconFlame, 6 | title: 'Flexible', 7 | description: 8 | 'All components are built with Mantine theme, change colors, fonts, shadows and other properties.', 9 | }, 10 | 11 | { 12 | icon: IconMoonStars, 13 | title: 'Light and dark theme', 14 | description: 15 | 'Most components support both dark and light color schemes by default, no additional modifications needed.', 16 | }, 17 | 18 | { 19 | icon: IconLicense, 20 | title: 'Free for everyone', 21 | description: 22 | 'Free, open source, community-driven, MIT license. Use anywhere, including commercial projects.', 23 | }, 24 | ]; 25 | -------------------------------------------------------------------------------- /components/HomePage/CategoriesList/CategoriesList.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | padding-top: 80px; 3 | } 4 | 5 | .header { 6 | display: flex; 7 | align-items: center; 8 | margin-bottom: var(--mantine-spacing-lg); 9 | 10 | @media (max-width: em(755px)) { 11 | display: block; 12 | } 13 | } 14 | 15 | .title { 16 | font-weight: 500; 17 | line-height: 1; 18 | color: light-dark(var(--mantine-color-black), var(--mantine-color-white)); 19 | } 20 | 21 | .count { 22 | margin-left: var(--mantine-spacing-md); 23 | margin-top: var(--mantine-spacing-xs); 24 | 25 | @media (max-width: em(755px)) { 26 | margin-top: var(--mantine-spacing-xs); 27 | margin-left: 0; 28 | } 29 | } 30 | 31 | .group { 32 | & + & { 33 | margin-top: calc(var(--mantine-spacing-xl) * 4); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /components/HomePage/CategoryCard/CategoryCard.module.css: -------------------------------------------------------------------------------- 1 | .image { 2 | transition: transform 500ms ease; 3 | 4 | &[data-dark] { 5 | @mixin light { 6 | display: none; 7 | } 8 | } 9 | 10 | &[data-light] { 11 | @mixin dark { 12 | display: none; 13 | } 14 | } 15 | } 16 | 17 | .card { 18 | cursor: pointer; 19 | position: relative; 20 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-5)); 21 | border: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-7)); 22 | 23 | @mixin hover { 24 | .image { 25 | transform: scale(1.025); 26 | } 27 | } 28 | } 29 | 30 | .title { 31 | margin-top: var(--mantine-spacing-sm); 32 | } 33 | 34 | .description { 35 | color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2)); 36 | margin-top: 2px; 37 | } 38 | 39 | .imageWrapper { 40 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-8)); 41 | min-height: 154px; 42 | } 43 | -------------------------------------------------------------------------------- /components/HomePage/HomePage.tsx: -------------------------------------------------------------------------------- 1 | import { CATEGORIES } from '../../data'; 2 | import { Shell } from '../Shell'; 3 | import { Banner } from './Banner/Banner'; 4 | import { CategoriesList } from './CategoriesList/CategoriesList'; 5 | 6 | interface HomePageProps { 7 | componentsCountByCategory: Record<string, number>; 8 | } 9 | 10 | export function HomePage({ componentsCountByCategory }: HomePageProps) { 11 | const allComponentsCount = Object.keys(componentsCountByCategory).reduce( 12 | (acc, category) => acc + componentsCountByCategory[category], 13 | 0 14 | ); 15 | 16 | return ( 17 | <Shell> 18 | <Banner componentsCount={allComponentsCount} /> 19 | <div id="main"> 20 | <CategoriesList groups={CATEGORIES} componentsCountByCategory={componentsCountByCategory} /> 21 | </div> 22 | </Shell> 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /components/HotKeysHandler/HotKeysHandler.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useComputedColorScheme, useMantineColorScheme } from '@mantine/core'; 3 | import { useHotkeys } from '@mantine/hooks'; 4 | 5 | export function HotKeysHandler() { 6 | const { setColorScheme } = useMantineColorScheme(); 7 | const computedColorScheme = useComputedColorScheme('light'); 8 | useHotkeys( 9 | [['mod + J', () => setColorScheme(computedColorScheme === 'light' ? 'dark' : 'light')]], 10 | [] 11 | ); 12 | return <>{null}</>; 13 | } 14 | -------------------------------------------------------------------------------- /components/HotKeysHandler/index.ts: -------------------------------------------------------------------------------- 1 | export { HotKeysHandler } from './HotKeysHandler'; 2 | -------------------------------------------------------------------------------- /components/PageHead/PageHead.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Head from 'next/head'; 3 | 4 | interface PageHeadProps { 5 | title: string | undefined; 6 | description: string | undefined; 7 | } 8 | 9 | const metaDescription = 'Mantine UI: 120+ premade responsive components built with Mantine'; 10 | 11 | export function PageHead({ title, description }: PageHeadProps) { 12 | const _title = title ? `${title} | Mantine` : 'Mantine'; 13 | const _description = description || metaDescription; 14 | return ( 15 | <Head> 16 | <title>{_title}</title> 17 | <meta name="description" content={_description} /> 18 | <meta name="og:title" content={_title} /> 19 | <meta name="og:description" content={_description} /> 20 | <meta name="twitter:title" content={_title} /> 21 | <meta name="twitter:description" content={_description} /> 22 | </Head> 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /components/PageHead/index.ts: -------------------------------------------------------------------------------- 1 | export { PageHead } from './PageHead'; 2 | -------------------------------------------------------------------------------- /components/Search/Search.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from 'next/router'; 2 | import { IconSearch } from '@tabler/icons-react'; 3 | import { createSpotlight, Spotlight } from '@mantine/spotlight'; 4 | 5 | export const [searchStore, searchHandlers] = createSpotlight(); 6 | 7 | export function Search({ data }: { data: any[] }) { 8 | const router = useRouter(); 9 | 10 | const actions = data?.map((item) => ({ 11 | id: item.component, 12 | label: item.component, 13 | description: item.attributes.title, 14 | onClick: () => router.push(`/component/${item.slug}`), 15 | })); 16 | 17 | return ( 18 | <Spotlight 19 | store={searchStore} 20 | shortcut={['mod + K', 'mod + P', '/']} 21 | actions={actions || []} 22 | tagsToIgnore={[]} 23 | highlightQuery 24 | clearQueryOnClose 25 | radius="md" 26 | limit={7} 27 | nothingFound="Nothing found..." 28 | searchProps={{ 29 | leftSection: <IconSearch size={20} />, 30 | placeholder: 'Search components...', 31 | }} 32 | /> 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /components/Search/index.ts: -------------------------------------------------------------------------------- 1 | export { Search, searchHandlers } from './Search'; 2 | -------------------------------------------------------------------------------- /components/Shell/Shell.module.css: -------------------------------------------------------------------------------- 1 | .inner { 2 | display: flex; 3 | align-items: center; 4 | justify-content: space-between; 5 | height: 100%; 6 | } 7 | 8 | .main { 9 | padding-bottom: 120px; 10 | } 11 | -------------------------------------------------------------------------------- /components/Shell/index.ts: -------------------------------------------------------------------------------- 1 | export { Shell } from './Shell'; 2 | -------------------------------------------------------------------------------- /components/StoryWrapper/StoryWrapper.tsx: -------------------------------------------------------------------------------- 1 | import { CanvasAttributes } from '../../data'; 2 | import { ComponentPreview } from '../ComponentPreview/ComponentPreview'; 3 | 4 | interface StoryWrapperProps { 5 | attributes: CanvasAttributes; 6 | component: React.FC<any>; 7 | } 8 | 9 | export function StoryWrapper({ attributes, component: Component }: StoryWrapperProps) { 10 | return ( 11 | <ComponentPreview canvas={attributes.canvas} withSpacing> 12 | <Component {...(attributes.props || null)} /> 13 | </ComponentPreview> 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /data/images/buttons-dark.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="370" height="54" x="65" y="98" fill="#FFD43B" rx="27"/><rect width="289" height="12" x="105" y="119" fill="#141517" rx="6"/></svg> 2 | -------------------------------------------------------------------------------- /data/images/buttons-light.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="370" height="54" x="65" y="98" fill="#15AABF" rx="27"/><rect width="289" height="12" x="105" y="119" fill="#fff" rx="6"/></svg> 2 | -------------------------------------------------------------------------------- /data/images/carousels-dark.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><path stroke="#373A40" stroke-linecap="round" stroke-linejoin="round" stroke-width="5.5" d="M424 117l8 8-8 8M75 133l-8-8 8-8"/><rect width="315" height="161" x="92" y="45" fill="#373A40" rx="21"/><path stroke="#5C5F66" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.667" d="M256.375 116.333h.023M260.958 107.167h-22.916a6.875 6.875 0 00-6.875 6.875v22.916a6.875 6.875 0 006.875 6.875h22.916a6.875 6.875 0 006.875-6.875v-22.916a6.875 6.875 0 00-6.875-6.875z"/><path stroke="#5C5F66" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.667" d="M231.167 132.375l9.166-9.167c1.045-1.005 2.231-1.535 3.438-1.535 1.207 0 2.392.53 3.437 1.535l11.459 11.459M254.083 130.083l2.292-2.292c1.045-1.005 2.231-1.535 3.438-1.535 1.206 0 2.392.53 3.437 1.535l4.583 4.584"/></svg> -------------------------------------------------------------------------------- /data/images/carousels-light.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><path stroke="#DFE4EA" stroke-linecap="round" stroke-linejoin="round" stroke-width="5.5" d="M424 117l8 8-8 8M75 133l-8-8 8-8"/><rect width="315" height="161" x="92" y="45" fill="#DFE4EA" rx="21"/><path stroke="#B7BCC2" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.667" d="M256.375 116.333h.023M260.958 107.167h-22.916a6.875 6.875 0 00-6.875 6.875v22.916a6.875 6.875 0 006.875 6.875h22.916a6.875 6.875 0 006.875-6.875v-22.916a6.875 6.875 0 00-6.875-6.875z"/><path stroke="#B7BCC2" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.667" d="M231.167 132.375l9.166-9.167c1.045-1.005 2.231-1.535 3.438-1.535 1.207 0 2.392.53 3.437 1.535l11.459 11.459M254.083 130.083l2.292-2.292c1.045-1.005 2.231-1.535 3.438-1.535 1.206 0 2.392.53 3.437 1.535l4.583 4.584"/></svg> -------------------------------------------------------------------------------- /data/images/color-scheme-dark.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="149" height="77" x="324" y="164" fill="#FFD43B" rx="38.5" transform="rotate(-180 324 164)"/><rect width="51" height="51" x="237" y="151" fill="#fff" rx="25.5" transform="rotate(-180 237 151)"/><path stroke="#8B7420" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.75" d="M288 133.333a8.333 8.333 0 100-16.666 8.333 8.333 0 000 16.666zM276.125 136.875l-1.458 1.458M269.25 125h2.083-2.083zM288 106.25v2.083-2.083zM304.667 125h2.083-2.083zM288 141.667v2.083-2.083zm-13.333-30l1.458 1.458-1.458-1.458zm26.666 0l-1.458 1.458 1.458-1.458zm-1.458 25.208l1.458 1.458-1.458-1.458z"/></svg> 2 | -------------------------------------------------------------------------------- /data/images/color-scheme-light.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="149" height="77" x="175" y="87" fill="#DFE4EA" rx="38.5"/><rect width="51" height="51" x="262" y="100" fill="#fff" rx="25.5"/><path stroke="#B7BCC2" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.75" d="M211 107.25h.819a15.621 15.621 0 00-2.547 19.835 15.626 15.626 0 0019.047 6.094 18.751 18.751 0 01-25.342 9.749 18.742 18.742 0 01-7.567-6.535 18.74 18.74 0 01-.94-19.25 18.748 18.748 0 0116.53-9.91v.017zM221.417 109.333a4.17 4.17 0 004.166 4.167 4.164 4.164 0 00-4.166 4.167 4.164 4.164 0 00-1.221-2.946 4.164 4.164 0 00-2.946-1.221 4.167 4.167 0 004.167-4.167zM227.667 121.833V126m-2.084-2.083h4.167-4.167z"/></svg> 2 | -------------------------------------------------------------------------------- /data/images/dnd-dark.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="370" height="23" x="64.5" y="45.5" fill="#32363B" stroke="#373A40" rx="4.5"/><rect width="370" height="23" x="64.5" y="79.5" fill="#32363B" stroke="#373A40" rx="4.5"/><rect width="384" height="35" x="57.5" y="98.5" fill="#32363B" stroke="#4C525A" rx="4.5"/><rect width="370" height="23" x="64.5" y="147.5" fill="#32363B" stroke="#373A40" rx="4.5"/><rect width="370" height="23" x="64.5" y="181.5" fill="#32363B" stroke="#373A40" rx="4.5"/></svg> 2 | -------------------------------------------------------------------------------- /data/images/grids-dark.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="116" height="144" x="64" y="53" fill="#373A40" rx="11"/><rect width="116" height="66" x="192" y="53" fill="#373A40" rx="11"/><rect width="116" height="66" x="192" y="131" fill="#373A40" rx="11"/><rect width="116" height="144" x="320" y="53" fill="#373A40" rx="11"/></svg> 2 | -------------------------------------------------------------------------------- /data/images/grids-light.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="115" height="143" x="64.5" y="53.5" fill="#fff" stroke="#DEE2E6" rx="10.5"/><rect width="115" height="65" x="192.5" y="53.5" fill="#fff" stroke="#DEE2E6" rx="10.5"/><rect width="115" height="65" x="192.5" y="131.5" fill="#fff" stroke="#DEE2E6" rx="10.5"/><rect width="115" height="143" x="320.5" y="53.5" fill="#fff" stroke="#DEE2E6" rx="10.5"/></svg> 2 | -------------------------------------------------------------------------------- /data/images/sliders-dark.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="371" height="26" x="64" y="112" fill="#373A40" rx="13"/><path fill="#FFD43B" d="M64 125c0-7.18 5.82-13 13-13h169v26H77c-7.18 0-13-5.82-13-13z"/><rect width="22" height="22" x="234" y="114" fill="#EEC535" stroke="#fff" stroke-width="4" rx="11"/></svg> 2 | -------------------------------------------------------------------------------- /data/images/sliders-light.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="371" height="26" x="64" y="112" fill="#E7ECF1" rx="13"/><path fill="#15AABF" d="M64 125c0-7.18 5.82-13 13-13h169v26H77c-7.18 0-13-5.82-13-13z"/><rect width="22" height="22" x="234" y="114" fill="#15AABF" stroke="#fff" stroke-width="4" rx="11"/></svg> 2 | -------------------------------------------------------------------------------- /data/images/toc-dark.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="100" height="4" x="198" y="57" fill="#5C5F66" rx="2"/><rect width="82" height="4" x="198" y="76" fill="#5C5F66" rx="2"/><rect width="110" height="4" x="198" y="95" fill="#5C5F66" rx="2"/><rect width="73" height="4" x="198" y="133" fill="#5C5F66" rx="2"/><rect width="105" height="4" x="198" y="152" fill="#5C5F66" rx="2"/><rect width="87" height="4" x="198" y="171" fill="#5C5F66" rx="2"/><rect width="56" height="4" x="198" y="190" fill="#5C5F66" rx="2"/><path fill="#5C5F66" d="M186 51h1v149h-1z"/><path fill="#FFD43B" d="M186 108h125a3 3 0 013 3v10a3 3 0 01-3 3H186v-16z"/><rect width="80" height="4" x="198" y="114" fill="#373A40" rx="2"/></svg> 2 | -------------------------------------------------------------------------------- /data/images/toc-light.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 250"><rect width="100" height="4" x="198" y="57" fill="#DEE2E6" rx="2"/><rect width="82" height="4" x="198" y="76" fill="#DEE2E6" rx="2"/><rect width="110" height="4" x="198" y="95" fill="#DEE2E6" rx="2"/><rect width="73" height="4" x="198" y="133" fill="#DEE2E6" rx="2"/><rect width="105" height="4" x="198" y="152" fill="#DEE2E6" rx="2"/><rect width="87" height="4" x="198" y="171" fill="#DEE2E6" rx="2"/><rect width="56" height="4" x="198" y="190" fill="#DEE2E6" rx="2"/><path fill="#DEE2E6" d="M186 51h1v149h-1z"/><path fill="#15AABF" d="M186 108h125a3 3 0 013 3v10a3 3 0 01-3 3H186v-16z"/><rect width="80" height="4" x="198" y="114" fill="#fff" rx="2"/></svg> 2 | -------------------------------------------------------------------------------- /data/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './categories'; 3 | -------------------------------------------------------------------------------- /data/types.ts: -------------------------------------------------------------------------------- 1 | export interface Category { 2 | slug: string; 3 | name: string; 4 | images: { dark: string; light: string }; 5 | } 6 | 7 | export interface CategoriesGroup { 8 | name: string; 9 | categories: Category[]; 10 | } 11 | 12 | export interface CanvasAttributes { 13 | responsive?: boolean; 14 | dimmed?: boolean; 15 | canvas: { center: boolean; maxWidth?: number }; 16 | category: string; 17 | title: string; 18 | props?: Record<string, any>; 19 | } 20 | 21 | export interface UiComponent { 22 | component: string; 23 | slug: string; 24 | code: { fileName: string; language: string; code: string }[]; 25 | attributes: CanvasAttributes; 26 | } 27 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import mantine from 'eslint-config-mantine'; 2 | import tseslint from 'typescript-eslint'; 3 | 4 | export default tseslint.config(...mantine, { ignores: ['**/*.{mjs,cjs,js,d.ts,d.mts}'] }); 5 | -------------------------------------------------------------------------------- /lib/ActionToggle/ActionToggle.module.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | width: 22px; 3 | height: 22px; 4 | } 5 | 6 | .dark { 7 | @mixin dark { 8 | display: none; 9 | } 10 | 11 | @mixin light { 12 | display: block; 13 | } 14 | } 15 | 16 | .light { 17 | @mixin light { 18 | display: none; 19 | } 20 | 21 | @mixin dark { 22 | display: block; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/ActionToggle/ActionToggle.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import { ActionToggle } from './ActionToggle'; 3 | import attributes from './attributes.json'; 4 | 5 | export default { title: 'ActionToggle' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ActionToggle} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ActionToggle/ActionToggle.tsx: -------------------------------------------------------------------------------- 1 | import { IconMoon, IconSun } from '@tabler/icons-react'; 2 | import cx from 'clsx'; 3 | import { ActionIcon, Group, useComputedColorScheme, useMantineColorScheme } from '@mantine/core'; 4 | import classes from './ActionToggle.module.css'; 5 | 6 | export function ActionToggle() { 7 | const { setColorScheme } = useMantineColorScheme(); 8 | const computedColorScheme = useComputedColorScheme('light', { getInitialValueInEffect: true }); 9 | 10 | return ( 11 | <Group justify="center"> 12 | <ActionIcon 13 | onClick={() => setColorScheme(computedColorScheme === 'light' ? 'dark' : 'light')} 14 | variant="default" 15 | size="xl" 16 | radius="md" 17 | aria-label="Toggle color scheme" 18 | > 19 | <IconSun className={cx(classes.icon, classes.light)} stroke={1.5} /> 20 | <IconMoon className={cx(classes.icon, classes.dark)} stroke={1.5} /> 21 | </ActionIcon> 22 | </Group> 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /lib/ActionToggle/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Color scheme toggle", 3 | "category": "buttons", 4 | "canvas": { 5 | "center": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/ActionsGrid/ActionsGrid.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); 3 | } 4 | 5 | .title { 6 | font-family: Outfit, var(--mantine-font-family); 7 | font-weight: 500; 8 | } 9 | 10 | .item { 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | justify-content: center; 15 | text-align: center; 16 | border-radius: var(--mantine-radius-md); 17 | height: 90px; 18 | background-color: var(--mantine-color-body); 19 | transition: 20 | box-shadow 150ms ease, 21 | transform 100ms ease; 22 | 23 | @mixin hover { 24 | box-shadow: var(--mantine-shadow-md); 25 | transform: scale(1.05); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/ActionsGrid/ActionsGrid.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import { ActionsGrid } from './ActionsGrid'; 3 | import attributes from './attributes.json'; 4 | 5 | export default { title: 'ActionsGrid' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ActionsGrid} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ActionsGrid/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with actions grid", 3 | "category": "app-cards", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ArticleCard/ArticleCard.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | position: relative; 3 | background-color: var(--mantine-color-body); 4 | } 5 | 6 | .rating { 7 | position: absolute; 8 | top: var(--mantine-spacing-xs); 9 | right: 12px; 10 | pointer-events: none; 11 | } 12 | 13 | .title { 14 | display: block; 15 | font-family: Outfit, var(--mantine-font-family); 16 | margin-top: var(--mantine-spacing-md); 17 | margin-bottom: 5px; 18 | } 19 | 20 | .action { 21 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5)); 22 | 23 | @mixin hover { 24 | background-color: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-6)); 25 | } 26 | } 27 | 28 | .footer { 29 | margin-top: var(--mantine-spacing-md); 30 | } 31 | -------------------------------------------------------------------------------- /lib/ArticleCard/ArticleCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import { ArticleCard } from './ArticleCard'; 3 | import attributes from './attributes.json'; 4 | 5 | export default { title: 'ArticleCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ArticleCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ArticleCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Article card with image", 3 | "category": "article-cards", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 320 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/ArticleCardFooter/ArticleCardFooter.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: var(--mantine-color-body); 3 | } 4 | 5 | .title { 6 | font-family: Outfit, var(--mantine-font-family); 7 | font-weight: 450; 8 | margin-top: var(--mantine-spacing-xs); 9 | } 10 | 11 | .footer { 12 | padding: var(--mantine-spacing-xs) var(--mantine-spacing-lg); 13 | margin-top: var(--mantine-spacing-md); 14 | border-top: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5)); 15 | } 16 | -------------------------------------------------------------------------------- /lib/ArticleCardFooter/ArticleCardFooter.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import { ArticleCardFooter } from './ArticleCardFooter'; 3 | import attributes from './attributes.json'; 4 | 5 | export default { title: 'ArticleCardFooter' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ArticleCardFooter} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ArticleCardFooter/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Article card with footer", 3 | "category": "article-cards", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 320 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/ArticleCardImage/ArticleCardImage.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | height: 440px; 3 | display: flex; 4 | flex-direction: column; 5 | justify-content: space-between; 6 | align-items: flex-start; 7 | background-size: cover; 8 | background-position: center; 9 | background-image: url(https://images.unsplash.com/photo-1508193638397-1c4234db14d8?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80); 10 | } 11 | 12 | .title { 13 | font-family: Outfit, var(--mantine-font-family); 14 | font-weight: 600; 15 | color: var(--mantine-color-white); 16 | line-height: 1.2; 17 | font-size: 32px; 18 | margin-top: var(--mantine-spacing-xs); 19 | } 20 | 21 | .category { 22 | color: var(--mantine-color-white); 23 | opacity: 0.7; 24 | font-weight: 700; 25 | text-transform: uppercase; 26 | } 27 | -------------------------------------------------------------------------------- /lib/ArticleCardImage/ArticleCardImage.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import { ArticleCardImage } from './ArticleCardImage'; 3 | import attributes from './attributes.json'; 4 | 5 | export default { title: 'ArticleCardImage' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ArticleCardImage} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ArticleCardImage/ArticleCardImage.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Paper, Text, Title } from '@mantine/core'; 2 | import classes from './ArticleCardImage.module.css'; 3 | 4 | export function ArticleCardImage() { 5 | return ( 6 | <Paper shadow="md" p="xl" radius="md" className={classes.card}> 7 | <div> 8 | <Text className={classes.category} size="xs"> 9 | nature 10 | </Text> 11 | <Title order={3} className={classes.title}> 12 | Best forests to visit in North America 13 | </Title> 14 | </div> 15 | <Button variant="white" color="dark"> 16 | Read article 17 | </Button> 18 | </Paper> 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /lib/ArticleCardImage/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with background image", 3 | "category": "article-cards", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 320 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ArticleCardVertical/ArticleCardVertical.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: var(--mantine-color-body); 3 | display: flex; 4 | flex-wrap: nowrap; 5 | flex-direction: row; 6 | 7 | @mixin smaller-than 755px { 8 | flex-direction: column; 9 | } 10 | } 11 | 12 | .image { 13 | max-width: 220px; 14 | 15 | @mixin smaller-than 755px { 16 | max-width: 100%; 17 | max-height: 180px; 18 | } 19 | } 20 | 21 | .title { 22 | font-weight: 500; 23 | font-family: Outfit, var(--mantine-font-family); 24 | line-height: 1.2; 25 | } 26 | 27 | .body { 28 | padding: var(--mantine-spacing-md); 29 | } 30 | -------------------------------------------------------------------------------- /lib/ArticleCardVertical/ArticleCardVertical.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import { ArticleCardVertical } from './ArticleCardVertical'; 3 | import attributes from './attributes.json'; 4 | 5 | export default { title: 'ArticleCardVertical' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ArticleCardVertical} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ArticleCardVertical/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Vertical article card", 3 | "category": "article-cards", 4 | "dimmed": true, 5 | "responsive": true, 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 520 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/ArticlesCardsGrid/ArticlesCardsGrid.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | border: 1px solid transparent; 3 | position: relative; 4 | transition: 5 | border-color 150ms ease, 6 | transform 150ms ease, 7 | box-shadow 150ms ease; 8 | 9 | @mixin hover { 10 | z-index: 1; 11 | transform: scale(1.01); 12 | box-shadow: var(--mantine-shadow-md); 13 | border-color: light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5)); 14 | } 15 | } 16 | 17 | .date { 18 | text-transform: uppercase; 19 | font-weight: 500; 20 | color: var(--mantine-color-dimmed); 21 | font-size: var(--mantine-font-size-xs); 22 | margin-top: var(--mantine-spacing-xs); 23 | } 24 | 25 | .title { 26 | font-family: 'Outfit', var(--mantine-font-family); 27 | font-weight: 500; 28 | font-size: var(--mantine-font-size-lg); 29 | } 30 | -------------------------------------------------------------------------------- /lib/ArticlesCardsGrid/ArticlesCardsGrid.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import { ArticlesCardsGrid } from './ArticlesCardsGrid'; 3 | import attributes from './attributes.json'; 4 | 5 | export default { title: 'ArticlesCardsGrid' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ArticlesCardsGrid} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ArticlesCardsGrid/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Articles cards grid", 3 | "category": "article-cards", 4 | "changelog": "september-2022", 5 | "responsive": true, 6 | "canvas": { 7 | "center": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/AuthenticationForm/AuthenticationForm.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { AuthenticationForm } from './AuthenticationForm'; 4 | 5 | export default { title: 'AuthenticationForm' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={AuthenticationForm} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/AuthenticationForm/TwitterButton.tsx: -------------------------------------------------------------------------------- 1 | import { Button, ButtonProps } from '@mantine/core'; 2 | import { TwitterIcon } from '@mantinex/dev-icons'; 3 | 4 | export function TwitterButton(props: ButtonProps & React.ComponentPropsWithoutRef<'button'>) { 5 | return ( 6 | <Button leftSection={<TwitterIcon size={16} color="#00ACEE" />} variant="default" {...props} /> 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /lib/AuthenticationForm/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Authentication form", 3 | "category": "authentication", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 420 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/AuthenticationImage/AuthenticationImage.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | min-height: 900px; 3 | background-size: cover; 4 | background-image: url(https://images.unsplash.com/photo-1484242857719-4b9144542727?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1280&q=80); 5 | } 6 | 7 | .form { 8 | border-right: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-7)); 9 | min-height: 900px; 10 | max-width: 450px; 11 | padding: 30px; 12 | padding-top: 80px; 13 | border-radius: 0; 14 | 15 | @media (max-width: $mantine-breakpoint-sm) { 16 | max-width: 100%; 17 | } 18 | } 19 | 20 | .title { 21 | color: light-dark(var(--mantine-color-black), var(--mantine-color-white)); 22 | font-family: Outfit, var(--mantine-font-family); 23 | font-weight: 500; 24 | text-align: center; 25 | margin-top: var(--mantine-spacing-md); 26 | margin-bottom: 50px; 27 | } 28 | -------------------------------------------------------------------------------- /lib/AuthenticationImage/AuthenticationImage.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { AuthenticationImage } from './AuthenticationImage'; 4 | 5 | export default { title: 'AuthenticationImage' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={AuthenticationImage} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/AuthenticationImage/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Authentication page with image", 3 | "category": "authentication", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/AuthenticationTitle/AuthenticationTitle.module.css: -------------------------------------------------------------------------------- 1 | .title { 2 | font-family: Outfit, var(--mantine-font-family); 3 | font-weight: 500; 4 | } 5 | 6 | .subtitle { 7 | color: var(--mantine-color-dimmed); 8 | font-size: var(--mantine-font-size-sm); 9 | text-align: center; 10 | margin-top: 5px; 11 | } 12 | -------------------------------------------------------------------------------- /lib/AuthenticationTitle/AuthenticationTitle.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { AuthenticationTitle } from './AuthenticationTitle'; 4 | 5 | export default { title: 'AuthenticationTitle' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={AuthenticationTitle} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/AuthenticationTitle/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Authentication form with title", 3 | "category": "authentication", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/AutocompleteLoading/AutocompleteLoading.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { AutocompleteLoading } from './AutocompleteLoading'; 4 | 5 | export default { title: 'AutocompleteLoading' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={AutocompleteLoading} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/AutocompleteLoading/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Autocomplete async data", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/BadgeCard/BadgeCard.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7)); 3 | } 4 | 5 | .section { 6 | border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 7 | padding-left: var(--mantine-spacing-md); 8 | padding-right: var(--mantine-spacing-md); 9 | padding-bottom: var(--mantine-spacing-md); 10 | } 11 | 12 | .like { 13 | color: var(--mantine-color-red-6); 14 | width: 20px; 15 | height: 20px; 16 | } 17 | 18 | .label { 19 | text-transform: uppercase; 20 | font-size: var(--mantine-font-size-xs); 21 | font-weight: 700; 22 | } 23 | -------------------------------------------------------------------------------- /lib/BadgeCard/BadgeCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { BadgeCard } from './BadgeCard'; 4 | 5 | export default { title: 'BadgeCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={BadgeCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/BadgeCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with badges", 3 | "category": "app-cards", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 370 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/ButtonCopy/ButtonCopy.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ButtonCopy } from './ButtonCopy'; 4 | 5 | export default { title: 'ButtonCopy' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ButtonCopy} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ButtonCopy/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Copy to clipboard button", 3 | "category": "buttons", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 240 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ButtonMenu/ButtonMenu.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ButtonMenu } from './ButtonMenu'; 4 | 5 | export default { title: 'ButtonMenu' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ButtonMenu} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ButtonMenu/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Button with menu", 3 | "category": "buttons", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 120 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ButtonProgress/ButtonProgress.module.css: -------------------------------------------------------------------------------- 1 | .button { 2 | position: relative; 3 | transition: background-color 150ms ease; 4 | } 5 | 6 | .progress { 7 | position: absolute; 8 | top: -1px; 9 | left: -1px; 10 | right: -1px; 11 | bottom: -1px; 12 | height: auto; 13 | background-color: transparent; 14 | z-index: 0; 15 | } 16 | 17 | .label { 18 | position: relative; 19 | z-index: 1; 20 | } 21 | -------------------------------------------------------------------------------- /lib/ButtonProgress/ButtonProgress.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ButtonProgress } from './ButtonProgress'; 4 | 5 | export default { title: 'ButtonProgress' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ButtonProgress} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ButtonProgress/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Button with loading progress", 3 | "category": "buttons", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 220 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/CardGradient/CardGradient.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | position: relative; 3 | cursor: pointer; 4 | overflow: hidden; 5 | transition: 6 | transform 150ms ease, 7 | box-shadow 100ms ease; 8 | padding: var(--mantine-spacing-xl); 9 | padding-left: calc(var(--mantine-spacing-xl) * 1.5); 10 | 11 | @mixin hover { 12 | box-shadow: var(--mantine-shadow-sm); 13 | transform: scale(1.01); 14 | } 15 | 16 | &::before { 17 | content: ''; 18 | position: absolute; 19 | top: 0; 20 | bottom: 0; 21 | left: 0; 22 | width: 6px; 23 | background-image: linear-gradient( 24 | 0, 25 | var(--mantine-color-pink-6), 26 | var(--mantine-color-orange-6) 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/CardGradient/CardGradient.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { CardGradient } from './CardGradient'; 4 | 5 | export default { title: 'CardGradient' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={CardGradient} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/CardGradient/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with gradient border", 3 | "category": "article-cards", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 360 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/CardWithStats/CardWithStats.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: var(--mantine-color-body); 3 | } 4 | 5 | .footer { 6 | display: flex; 7 | justify-content: space-between; 8 | padding: var(--mantine-spacing-sm) var(--mantine-spacing-lg); 9 | border-top: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5)); 10 | } 11 | 12 | .title { 13 | font-family: Outfit, var(--mantine-font-family); 14 | font-weight: 500; 15 | line-height: 1; 16 | font-size: var(--mantine-font-size-sm); 17 | } 18 | -------------------------------------------------------------------------------- /lib/CardWithStats/CardWithStats.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { CardWithStats } from './CardWithStats'; 4 | 5 | export default { title: 'CardWithStats' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={CardWithStats} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/CardWithStats/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with stats", 3 | "category": "app-cards", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 320 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/CardsCarousel/CardsCarousel.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | height: 440px; 3 | display: flex; 4 | flex-direction: column; 5 | justify-content: space-between; 6 | align-items: flex-start; 7 | background-size: cover; 8 | background-position: center; 9 | } 10 | 11 | .title { 12 | font-family: Outfit, sans-serif; 13 | font-weight: 600; 14 | color: var(--mantine-color-white); 15 | line-height: 1.2; 16 | font-size: 32px; 17 | margin-top: var(--mantine-spacing-xs); 18 | } 19 | 20 | .category { 21 | color: var(--mantine-color-white); 22 | opacity: 0.7; 23 | font-weight: 700; 24 | text-transform: uppercase; 25 | } 26 | -------------------------------------------------------------------------------- /lib/CardsCarousel/CardsCarousel.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { CardsCarousel } from './CardsCarousel'; 4 | 5 | export default { title: 'CardsCarousel' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={CardsCarousel} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/CardsCarousel/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Carousel with cards", 3 | "category": "carousels", 4 | "changelog": "september-2022", 5 | "responsive": true, 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 820 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/CarouselCard/CarouselCard.module.css: -------------------------------------------------------------------------------- 1 | .price { 2 | color: var(--mantine-color-bright); 3 | } 4 | 5 | .carousel { 6 | @mixin hover { 7 | .carouselControls { 8 | opacity: 1; 9 | } 10 | } 11 | } 12 | 13 | .carouselControls { 14 | transition: opacity 150ms ease; 15 | opacity: 0; 16 | } 17 | 18 | .carouselIndicator { 19 | width: 4px; 20 | height: 4px; 21 | transition: width 250ms ease; 22 | 23 | &[data-active] { 24 | width: 16px; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/CarouselCard/CarouselCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { CarouselCard } from './CarouselCard'; 4 | 5 | export default { title: 'CarouselCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={CarouselCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/CarouselCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with carousel", 3 | "category": "carousels", 4 | "changelog": "september-2022", 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 350 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/CheckboxCard/CheckboxCard.module.css: -------------------------------------------------------------------------------- 1 | .button { 2 | display: flex; 3 | width: 100%; 4 | border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-8)); 5 | border-radius: var(--mantine-radius-md); 6 | padding: var(--mantine-spacing-lg); 7 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-8)); 8 | 9 | @mixin hover { 10 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-9)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/CheckboxCard/CheckboxCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { CheckboxCard } from './CheckboxCard'; 4 | 5 | export default { title: 'CheckboxCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={CheckboxCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/CheckboxCard/CheckboxCard.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import { Checkbox, Text, UnstyledButton } from '@mantine/core'; 3 | import classes from './CheckboxCard.module.css'; 4 | 5 | export function CheckboxCard() { 6 | const [value, onChange] = useState(true); 7 | 8 | return ( 9 | <UnstyledButton onClick={() => onChange(!value)} className={classes.button}> 10 | <Checkbox 11 | checked={value} 12 | onChange={() => {}} 13 | tabIndex={-1} 14 | size="md" 15 | mr="xl" 16 | styles={{ input: { cursor: 'pointer' } }} 17 | aria-hidden 18 | /> 19 | 20 | <div> 21 | <Text fw={500} mb={7} lh={1}> 22 | @mantine/core 23 | </Text> 24 | <Text fz="sm" c="dimmed"> 25 | Core components library: inputs, buttons, overlays, etc. 26 | </Text> 27 | </div> 28 | </UnstyledButton> 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /lib/CheckboxCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with checkbox", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 400 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/CommentHtml/CommentHtml.module.css: -------------------------------------------------------------------------------- 1 | .comment { 2 | padding: var(--mantine-spacing-lg) var(--mantine-spacing-xl); 3 | } 4 | 5 | .body { 6 | padding-left: 54px; 7 | padding-top: var(--mantine-spacing-sm); 8 | font-size: var(--mantine-font-size-sm); 9 | } 10 | 11 | .content { 12 | & > p:last-child { 13 | margin-bottom: 0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/CommentHtml/CommentHtml.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { CommentHtml } from './CommentHtml'; 4 | 5 | export default { title: 'CommentHtml' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={CommentHtml} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/CommentHtml/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Comment with html content", 3 | "category": "comments", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 380 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/CommentSimple/CommentSimple.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { CommentSimple } from './CommentSimple'; 4 | 5 | export default { title: 'CommentSimple' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={CommentSimple} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/CommentSimple/CommentSimple.tsx: -------------------------------------------------------------------------------- 1 | import { Avatar, Group, Text } from '@mantine/core'; 2 | 3 | export function CommentSimple() { 4 | return ( 5 | <div> 6 | <Group> 7 | <Avatar 8 | src="https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/avatars/avatar-1.png" 9 | alt="Jacob Warnhalter" 10 | radius="xl" 11 | /> 12 | <div> 13 | <Text size="sm">Jacob Warnhalter</Text> 14 | <Text size="xs" c="dimmed"> 15 | 10 minutes ago 16 | </Text> 17 | </div> 18 | </Group> 19 | <Text pl={54} pt="sm" size="sm"> 20 | This Pokémon likes to lick its palms that are sweetened by being soaked in honey. Teddiursa 21 | concocts its own honey by blending fruits and pollen collected by Beedrill. Blastoise has 22 | water spouts that protrude from its shell. The water spouts are very accurate. 23 | </Text> 24 | </div> 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /lib/CommentSimple/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Comment", 3 | "category": "comments", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 380 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ContactUs/ContactIcons.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: flex; 3 | align-items: center; 4 | color: var(--mantine-color-white); 5 | } 6 | 7 | .icon { 8 | margin-right: var(--mantine-spacing-md); 9 | background-color: transparent; 10 | } 11 | 12 | .title { 13 | color: var(--mantine-color-blue-0); 14 | } 15 | 16 | .description { 17 | color: var(--mantine-color-white); 18 | } 19 | -------------------------------------------------------------------------------- /lib/ContactUs/ContactUs.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ContactUs } from './ContactUs'; 4 | 5 | export default { title: 'ContactUs' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ContactUs} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ContactUs/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Contact us form", 3 | "category": "contact", 4 | "responsive": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 1000 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/ContainedInputs/ContainedInput.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | position: relative; 3 | } 4 | 5 | .input { 6 | height: 54px; 7 | padding-top: 18px; 8 | } 9 | 10 | .label { 11 | position: absolute; 12 | pointer-events: none; 13 | font-size: var(--mantine-font-size-xs); 14 | padding-left: var(--mantine-spacing-sm); 15 | padding-top: calc(var(--mantine-spacing-sm) / 2); 16 | z-index: 1; 17 | } 18 | -------------------------------------------------------------------------------- /lib/ContainedInputs/ContainedInputs.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ContainedInputs } from './ContainedInputs'; 4 | 5 | export default { title: 'ContainedInputs' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ContainedInputs} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ContainedInputs/ContainedInputs.tsx: -------------------------------------------------------------------------------- 1 | import { Select, TextInput } from '@mantine/core'; 2 | import classes from './ContainedInput.module.css'; 3 | 4 | export function ContainedInputs() { 5 | return ( 6 | <> 7 | <TextInput label="Shipping address" placeholder="15329 Huston 21st" classNames={classes} /> 8 | 9 | <Select 10 | mt="md" 11 | comboboxProps={{ withinPortal: true }} 12 | data={['React', 'Angular', 'Svelte', 'Vue']} 13 | placeholder="Pick one" 14 | label="Your favorite library/framework" 15 | classNames={classes} 16 | /> 17 | </> 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /lib/ContainedInputs/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Inputs with label inside input", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/CookiesBanner/CookiesBanner.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { CookiesBanner } from './CookiesBanner'; 4 | 5 | export default { title: 'CookiesBanner' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={CookiesBanner} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/CookiesBanner/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Cookies banner", 3 | "category": "banners", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 420 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/CurrencyInput/CurrencyInput.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { CurrencyInput } from './CurrencyInput'; 4 | 5 | export default { title: 'CurrencyInput' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={CurrencyInput} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/CurrencyInput/CurrencyInput.tsx: -------------------------------------------------------------------------------- 1 | import { NativeSelect, TextInput } from '@mantine/core'; 2 | 3 | const data = [ 4 | { value: 'eur', label: '🇪🇺 EUR' }, 5 | { value: 'usd', label: '🇺🇸 USD' }, 6 | { value: 'cad', label: '🇨🇦 CAD' }, 7 | { value: 'gbp', label: '🇬🇧 GBP' }, 8 | { value: 'aud', label: '🇦🇺 AUD' }, 9 | ]; 10 | 11 | export function CurrencyInput() { 12 | const select = ( 13 | <NativeSelect 14 | data={data} 15 | rightSectionWidth={28} 16 | styles={{ 17 | input: { 18 | fontWeight: 500, 19 | borderTopLeftRadius: 0, 20 | borderBottomLeftRadius: 0, 21 | width: 92, 22 | marginRight: -2, 23 | }, 24 | }} 25 | /> 26 | ); 27 | 28 | return ( 29 | <TextInput 30 | type="number" 31 | placeholder="1000" 32 | label="Transfer amount" 33 | rightSection={select} 34 | rightSectionWidth={92} 35 | /> 36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /lib/CurrencyInput/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Number input with currency select", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/CustomSwitch/CustomSwitch.module.css: -------------------------------------------------------------------------------- 1 | .body { 2 | display: flex; 3 | align-items: center; 4 | } 5 | 6 | .track { 7 | width: 40px; 8 | height: 6px; 9 | overflow: visible; 10 | } 11 | 12 | .thumb { 13 | width: 20px; 14 | height: 20px; 15 | left: -2px; 16 | border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 17 | transition: 18 | background-color 100ms ease, 19 | left 100ms ease; 20 | 21 | input:checked + * > & { 22 | background-color: var(--mantine-color-blue-filled); 23 | left: calc(100% - 12px); 24 | border-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/CustomSwitch/CustomSwitch.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { CustomSwitch } from './CustomSwitch'; 4 | 5 | export default { title: 'CustomSwitch' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={CustomSwitch} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/CustomSwitch/CustomSwitch.tsx: -------------------------------------------------------------------------------- 1 | import { Group, Switch } from '@mantine/core'; 2 | import classes from './CustomSwitch.module.css'; 3 | 4 | export function CustomSwitch() { 5 | return ( 6 | <Group justify="center" p="md"> 7 | <Switch label="Custom Switch" classNames={classes} withThumbIndicator={false} /> 8 | </Group> 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /lib/CustomSwitch/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Custom switch", 3 | "category": "inputs", 4 | "changelog": "september-2022", 5 | "canvas": { 6 | "center": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/DndList/DndList.module.css: -------------------------------------------------------------------------------- 1 | .item { 2 | display: flex; 3 | align-items: center; 4 | border-radius: var(--mantine-radius-md); 5 | border: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5)); 6 | padding: var(--mantine-spacing-sm) var(--mantine-spacing-lg); 7 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-5)); 8 | margin-bottom: var(--mantine-spacing-sm); 9 | } 10 | 11 | .itemDragging { 12 | box-shadow: var(--mantine-shadow-sm); 13 | } 14 | 15 | .symbol { 16 | font-size: 30px; 17 | font-weight: 700; 18 | width: 60px; 19 | } 20 | -------------------------------------------------------------------------------- /lib/DndList/DndList.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { DndList } from './DndList'; 4 | 5 | export default { title: 'DndList' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={DndList} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/DndList/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Drag'n'drop list", 3 | "category": "dnd", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/DndListHandle/DndListHandle.module.css: -------------------------------------------------------------------------------- 1 | .item { 2 | display: flex; 3 | align-items: center; 4 | border-radius: var(--mantine-radius-md); 5 | border: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5)); 6 | padding: var(--mantine-spacing-sm) var(--mantine-spacing-lg); 7 | padding-left: calc(var(--mantine-spacing-xl) - var(--mantine-spacing-md)); 8 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-5)); 9 | margin-bottom: var(--mantine-spacing-sm); 10 | } 11 | 12 | .itemDragging { 13 | box-shadow: var(--mantine-shadow-sm); 14 | } 15 | 16 | .symbol { 17 | font-size: 30px; 18 | font-weight: 700; 19 | width: 60px; 20 | } 21 | 22 | .dragHandle { 23 | display: flex; 24 | align-items: center; 25 | justify-content: center; 26 | height: 100%; 27 | color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-1)); 28 | margin-right: var(--mantine-spacing-lg); 29 | } 30 | -------------------------------------------------------------------------------- /lib/DndListHandle/DndListHandle.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { DndListHandle } from './DndListHandle'; 4 | 5 | export default { title: 'DndListHandle' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={DndListHandle} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/DndListHandle/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Drag'n'drop list with handle", 3 | "category": "dnd", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/DndTable/DndTable.module.css: -------------------------------------------------------------------------------- 1 | .item { 2 | background-color: var(--mantine-color-body); 3 | } 4 | 5 | .dragHandle { 6 | width: 40px; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | height: 100%; 11 | color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-1)); 12 | } 13 | -------------------------------------------------------------------------------- /lib/DndTable/DndTable.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { DndTable } from './DndTable'; 4 | 5 | export default { title: 'DndTable' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={DndTable} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/DndTable/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Drag'n'drop table", 3 | "category": "dnd", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/DoubleHeader/DoubleHeader.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { DoubleHeader } from './DoubleHeader'; 4 | 5 | export default { title: 'DoubleHeader' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={DoubleHeader} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/DoubleHeader/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Header with multiple layers", 3 | "category": "headers", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/DoubleNavbar/DoubleNavbar.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { DoubleNavbar } from './DoubleNavbar'; 4 | 5 | export default { title: 'DoubleNavbar' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={DoubleNavbar} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/DoubleNavbar/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Navbar with 2 sections", 3 | "category": "navbars", 4 | "canvas": { 5 | "center": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/DropzoneButton/DropzoneButton.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: relative; 3 | margin-bottom: 30px; 4 | } 5 | 6 | .dropzone { 7 | border-width: 1px; 8 | padding-bottom: 50px; 9 | color: var(--mantine-color-bright); 10 | } 11 | 12 | .icon { 13 | color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-white)); 14 | } 15 | 16 | .control { 17 | position: absolute; 18 | width: 250px; 19 | left: calc(50% - 125px); 20 | bottom: -20px; 21 | } 22 | 23 | .description { 24 | text-align: center; 25 | font-size: var(--mantine-font-size-sm); 26 | color: var(--mantine-color-dimmed); 27 | margin-top: var(--mantine-spacing-xs); 28 | } 29 | -------------------------------------------------------------------------------- /lib/DropzoneButton/DropzoneButton.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { DropzoneButton } from './DropzoneButton'; 4 | 5 | export default { title: 'DropzoneButton' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={DropzoneButton} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/DropzoneButton/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Dropzone with button", 3 | "category": "dropzones", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/EmailBanner/EmailBanner.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { EmailBanner } from './EmailBanner'; 4 | 5 | export default { title: 'EmailBanner' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={EmailBanner} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/EmailBanner/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Email banner", 3 | "category": "banners", 4 | "responsive": true, 5 | "dimmed": true, 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 980 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/FaqSimple/FaqSimple.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | padding-top: calc(var(--mantine-spacing-xl) * 2); 3 | padding-bottom: calc(var(--mantine-spacing-xl) * 2); 4 | min-height: 650px; 5 | } 6 | 7 | .title { 8 | margin-bottom: calc(var(--mantine-spacing-xl) * 1.5); 9 | } 10 | 11 | .item { 12 | border-radius: var(--mantine-radius-md); 13 | margin-bottom: var(--mantine-spacing-lg); 14 | border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 15 | } 16 | -------------------------------------------------------------------------------- /lib/FaqSimple/FaqSimple.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FaqSimple } from './FaqSimple'; 4 | 5 | export default { title: 'FaqSimple' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FaqSimple} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FaqSimple/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "FAQ simple", 3 | "category": "faq", 4 | "canvas": { 5 | "center": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/FaqWithBg/FaqWithBg.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FaqWithBg } from './FaqWithBg'; 4 | 5 | export default { title: 'FaqWithBg' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FaqWithBg} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FaqWithBg/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Faq with background", 3 | "category": "faq", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/FaqWithHeader/ContactIcons.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: flex; 3 | align-items: center; 4 | color: var(--mantine-color-white); 5 | } 6 | 7 | .icon { 8 | margin-right: var(--mantine-spacing-md); 9 | background-image: linear-gradient( 10 | 135deg, 11 | var(--mantine-color-blue-4) 0%, 12 | var(--mantine-color-blue-6) 100% 13 | ); 14 | } 15 | 16 | .title { 17 | color: var(--mantine-color-gray-6); 18 | } 19 | 20 | .description { 21 | color: var(--mantine-color-black); 22 | } 23 | -------------------------------------------------------------------------------- /lib/FaqWithHeader/FaqWithHeader.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FaqWithHeader } from './FaqWithHeader'; 4 | 5 | export default { title: 'FaqWithHeader' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FaqWithHeader} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FaqWithHeader/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Faq page header", 3 | "category": "faq", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/FaqWithImage/FaqWithImage.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | padding-top: calc(var(--mantine-spacing-xl) * 2); 3 | padding-bottom: calc(var(--mantine-spacing-xl) * 2); 4 | } 5 | 6 | .title { 7 | margin-bottom: var(--mantine-spacing-md); 8 | padding-left: var(--mantine-spacing-md); 9 | color: light-dark(var(--mantine-color-black), var(--mantine-color-white)); 10 | font-family: Outfit, var(--mantine-font-family); 11 | font-weight: 500; 12 | } 13 | 14 | .item { 15 | font-size: var(--mantine-font-size-sm); 16 | color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1)); 17 | } 18 | -------------------------------------------------------------------------------- /lib/FaqWithImage/FaqWithImage.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FaqWithImage } from './FaqWithImage'; 4 | 5 | export default { title: 'FaqWithImage' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FaqWithImage} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FaqWithImage/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Faq with image", 3 | "category": "faq", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/FeaturesAsymmetrical/FeaturesAsymmetrical.module.css: -------------------------------------------------------------------------------- 1 | .feature { 2 | position: relative; 3 | padding-top: var(--mantine-spacing-xl); 4 | padding-left: var(--mantine-spacing-xl); 5 | } 6 | 7 | .overlay { 8 | position: absolute; 9 | height: 100px; 10 | width: 160px; 11 | top: 0; 12 | left: 0; 13 | background-color: var(--mantine-color-blue-light); 14 | z-index: 1; 15 | } 16 | 17 | .content { 18 | position: relative; 19 | z-index: 2; 20 | } 21 | 22 | .icon { 23 | color: var(--mantine-color-blue-filled); 24 | } 25 | 26 | .title { 27 | color: light-dark(var(--mantine-color-black), var(--mantine-color-white)); 28 | } 29 | -------------------------------------------------------------------------------- /lib/FeaturesAsymmetrical/FeaturesAsymmetrical.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FeaturesAsymmetrical } from './FeaturesAsymmetrical'; 4 | 5 | export default { title: 'FeaturesAsymmetrical' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FeaturesAsymmetrical} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FeaturesAsymmetrical/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Features with icons", 3 | "category": "features", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/FeaturesCard/FeaturesCard.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: var(--mantine-color-body); 3 | } 4 | 5 | .imageSection { 6 | padding: var(--mantine-spacing-md); 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 11 | } 12 | 13 | .label { 14 | margin-bottom: var(--mantine-spacing-xs); 15 | line-height: 1; 16 | font-weight: 700; 17 | font-size: var(--mantine-font-size-xs); 18 | letter-spacing: -0.25px; 19 | text-transform: uppercase; 20 | } 21 | 22 | .section { 23 | padding: var(--mantine-spacing-md); 24 | border-top: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 25 | } 26 | 27 | .icon { 28 | margin-right: 5px; 29 | color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-2)); 30 | } 31 | -------------------------------------------------------------------------------- /lib/FeaturesCard/FeaturesCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FeaturesCard } from './FeaturesCard'; 4 | 5 | export default { title: 'FeaturesCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FeaturesCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FeaturesCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with icon features", 3 | "category": "app-cards", 4 | "author": "rtivital", 5 | "dimmed": true, 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 320 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/FeaturesCards/FeaturesCards.module.css: -------------------------------------------------------------------------------- 1 | .title { 2 | font-size: 34px; 3 | font-weight: 500; 4 | 5 | @media (max-width: $mantine-breakpoint-sm) { 6 | font-size: 24px; 7 | } 8 | } 9 | 10 | .description { 11 | max-width: 600px; 12 | margin: auto; 13 | 14 | &::after { 15 | content: ''; 16 | display: block; 17 | background-color: var(--mantine-color-blue-filled); 18 | width: 45px; 19 | height: 2px; 20 | margin-top: var(--mantine-spacing-sm); 21 | margin-left: auto; 22 | margin-right: auto; 23 | } 24 | } 25 | 26 | .card { 27 | border: 1px solid light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-5)); 28 | } 29 | 30 | .cardTitle { 31 | &::after { 32 | content: ''; 33 | display: block; 34 | background-color: var(--mantine-color-blue-filled); 35 | width: 45px; 36 | height: 2px; 37 | margin-top: var(--mantine-spacing-sm); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/FeaturesCards/FeaturesCards.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FeaturesCards } from './FeaturesCards'; 4 | 5 | export default { title: 'FeaturesCards' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FeaturesCards} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FeaturesCards/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Features with cards", 3 | "category": "features", 4 | "changelog": "september-2022", 5 | "responsive": true, 6 | "canvas": { 7 | "center": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/FeaturesGrid/FeaturesGrid.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | padding-top: calc(var(--mantine-spacing-xl) * 4); 3 | padding-bottom: calc(var(--mantine-spacing-xl) * 4); 4 | } 5 | 6 | .title { 7 | font-family: Outfit, var(--mantine-font-family); 8 | font-weight: 500; 9 | margin-bottom: var(--mantine-spacing-md); 10 | text-align: center; 11 | 12 | @media (max-width: $mantine-breakpoint-sm) { 13 | font-size: 28px; 14 | text-align: left; 15 | } 16 | } 17 | 18 | .description { 19 | text-align: center; 20 | 21 | @media (max-width: $mantine-breakpoint-sm) { 22 | text-align: left; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/FeaturesGrid/FeaturesGrid.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FeaturesGrid } from './FeaturesGrid'; 4 | 5 | export default { title: 'FeaturesGrid' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FeaturesGrid} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FeaturesGrid/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Features with monotone icons", 3 | "category": "features", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/FeaturesImages/FeaturesImages.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FeaturesImages } from './FeaturesImages'; 4 | 5 | export default { title: 'FeaturesImages' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FeaturesImages} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FeaturesImages/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Features with image icons", 3 | "category": "features", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/FeaturesImages/images/index.ts: -------------------------------------------------------------------------------- 1 | import accountants from './accountants.svg'; 2 | import auditors from './auditors.svg'; 3 | import lawyers from './lawyers.svg'; 4 | import others from './others.svg'; 5 | 6 | export default { 7 | accountants: accountants.src, 8 | auditors: auditors.src, 9 | lawyers: lawyers.src, 10 | others: others.src, 11 | } as Record<string, any>; 12 | -------------------------------------------------------------------------------- /lib/FeaturesTitle/FeaturesTitle.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | padding: calc(var(--mantine-spacing-xl) * 2) var(--mantine-spacing-xl); 3 | } 4 | 5 | .title { 6 | font-family: Outfit, var(--mantine-font-family); 7 | font-size: 36px; 8 | font-weight: 500; 9 | line-height: 1.1; 10 | margin-bottom: var(--mantine-spacing-md); 11 | color: light-dark(var(--mantine-color-black), var(--mantine-color-white)); 12 | } 13 | -------------------------------------------------------------------------------- /lib/FeaturesTitle/FeaturesTitle.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FeaturesTitle } from './FeaturesTitle'; 4 | 5 | export default { title: 'FeaturesTitle' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FeaturesTitle} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FeaturesTitle/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Features with title", 3 | "category": "features", 4 | "responsive": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 1060 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/FloatingLabelInput/FloatingLabelInput.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FloatingLabelInput } from './FloatingLabelInput'; 4 | 5 | export default { title: 'FloatingLabelInput' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FloatingLabelInput} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FloatingLabelInput/FloatingLabelInput.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import { TextInput } from '@mantine/core'; 3 | import classes from './FloatingLabelInput.module.css'; 4 | 5 | export function FloatingLabelInput() { 6 | const [focused, setFocused] = useState(false); 7 | const [value, setValue] = useState(''); 8 | const floating = value.trim().length !== 0 || focused || undefined; 9 | 10 | return ( 11 | <TextInput 12 | label="Floating label" 13 | placeholder="OMG, it also has a placeholder" 14 | required 15 | classNames={classes} 16 | value={value} 17 | onChange={(event) => setValue(event.currentTarget.value)} 18 | onFocus={() => setFocused(true)} 19 | onBlur={() => setFocused(false)} 20 | mt="md" 21 | autoComplete="nope" 22 | data-floating={floating} 23 | labelProps={{ 'data-floating': floating }} 24 | /> 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /lib/FloatingLabelInput/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Input with floating label", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/FooterCentered/FooterCentered.module.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | margin-top: 120px; 3 | border-top: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5)); 4 | } 5 | 6 | .inner { 7 | display: flex; 8 | justify-content: space-between; 9 | align-items: center; 10 | padding: var(--mantine-spacing-md) var(--mantine-spacing-md); 11 | 12 | @media (max-width: $mantine-breakpoint-sm) { 13 | flex-direction: column; 14 | } 15 | } 16 | 17 | .links { 18 | @media (max-width: $mantine-breakpoint-sm) { 19 | margin-top: var(--mantine-spacing-lg); 20 | margin-bottom: var(--mantine-spacing-sm); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/FooterCentered/FooterCentered.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FooterCentered } from './FooterCentered'; 4 | 5 | export default { title: 'FooterCentered' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FooterCentered} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FooterCentered/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Footer with centered links", 3 | "category": "footers", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/FooterLinks/FooterLinks.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FooterLinks } from './FooterLinks'; 4 | 5 | export default { title: 'FooterLinks' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FooterLinks} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FooterLinks/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Footer with links", 3 | "category": "footers", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/FooterSimple/FooterSimple.module.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | margin-top: 120px; 3 | border-top: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5)); 4 | } 5 | 6 | .inner { 7 | display: flex; 8 | justify-content: space-between; 9 | align-items: center; 10 | padding-top: var(--mantine-spacing-xl); 11 | padding-bottom: var(--mantine-spacing-xl); 12 | 13 | @media (max-width: $mantine-breakpoint-xs) { 14 | flex-direction: column; 15 | } 16 | } 17 | 18 | .links { 19 | @media (max-width: $mantine-breakpoint-xs) { 20 | margin-top: var(--mantine-spacing-md); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/FooterSimple/FooterSimple.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FooterSimple } from './FooterSimple'; 4 | 5 | export default { title: 'FooterSimple' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FooterSimple} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FooterSimple/FooterSimple.tsx: -------------------------------------------------------------------------------- 1 | import { Anchor, Container, Group } from '@mantine/core'; 2 | import { MantineLogo } from '@mantinex/mantine-logo'; 3 | import classes from './FooterSimple.module.css'; 4 | 5 | const links = [ 6 | { link: '#', label: 'Contact' }, 7 | { link: '#', label: 'Privacy' }, 8 | { link: '#', label: 'Blog' }, 9 | { link: '#', label: 'Careers' }, 10 | ]; 11 | 12 | export function FooterSimple() { 13 | const items = links.map((link) => ( 14 | <Anchor<'a'> 15 | c="dimmed" 16 | key={link.label} 17 | href={link.link} 18 | onClick={(event) => event.preventDefault()} 19 | size="sm" 20 | > 21 | {link.label} 22 | </Anchor> 23 | )); 24 | 25 | return ( 26 | <div className={classes.footer}> 27 | <Container className={classes.inner}> 28 | <MantineLogo size={28} /> 29 | <Group className={classes.links}>{items}</Group> 30 | </Container> 31 | </div> 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /lib/FooterSimple/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Simple footer", 3 | "category": "footers", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/FooterSocial/FooterSocial.module.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | margin-top: 120px; 3 | border-top: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5)); 4 | } 5 | 6 | .inner { 7 | display: flex; 8 | justify-content: space-between; 9 | align-items: center; 10 | padding-top: var(--mantine-spacing-xl); 11 | padding-bottom: var(--mantine-spacing-xl); 12 | 13 | @media (max-width: $mantine-breakpoint-xs) { 14 | flex-direction: column; 15 | } 16 | } 17 | 18 | .links { 19 | @media (max-width: $mantine-breakpoint-xs) { 20 | margin-top: var(--mantine-spacing-md); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/FooterSocial/FooterSocial.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { FooterSocial } from './FooterSocial'; 4 | 5 | export default { title: 'FooterSocial' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={FooterSocial} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/FooterSocial/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Footer with social icons", 3 | "category": "footers", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ForgotPassword/ForgotPassword.module.css: -------------------------------------------------------------------------------- 1 | .title { 2 | font-size: 26px; 3 | font-weight: 500; 4 | font-family: Outfit, var(--mantine-font-family); 5 | } 6 | 7 | .controls { 8 | @media (max-width: $mantine-breakpoint-xs) { 9 | flex-direction: column-reverse; 10 | } 11 | } 12 | 13 | .control { 14 | @media (max-width: $mantine-breakpoint-xs) { 15 | width: 100%; 16 | text-align: center; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/ForgotPassword/ForgotPassword.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ForgotPassword } from './ForgotPassword'; 4 | 5 | export default { title: 'ForgotPassword' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ForgotPassword} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ForgotPassword/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Forgot password", 3 | "category": "authentication", 4 | "author": "rtivital", 5 | "dimmed": true, 6 | "responsive": true, 7 | "dependencies": [ 8 | "/core/container/", 9 | "/core/title/", 10 | "/core/anchor/", 11 | "/core/button/", 12 | "/core/text-input/", 13 | "/core/paper/", 14 | "@tabler/icons-react" 15 | ], 16 | "canvas": { 17 | "center": false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/ForgotPasswordInput/ForgotPasswordInput.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ForgotPasswordInput } from './ForgotPasswordInput'; 4 | 5 | export default { title: 'ForgotPasswordInput' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ForgotPasswordInput} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ForgotPasswordInput/ForgotPasswordInput.tsx: -------------------------------------------------------------------------------- 1 | import { Anchor, Group, PasswordInput, Text } from '@mantine/core'; 2 | 3 | export function ForgotPasswordInput() { 4 | return ( 5 | <> 6 | <Group justify="space-between" mb={5}> 7 | <Text component="label" htmlFor="your-password" size="sm" fw={500}> 8 | Your password 9 | </Text> 10 | 11 | <Anchor href="#" onClick={(event) => event.preventDefault()} pt={2} fw={500} fz="xs"> 12 | Forgot your password? 13 | </Anchor> 14 | </Group> 15 | <PasswordInput placeholder="Your password" id="your-password" /> 16 | </> 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /lib/ForgotPasswordInput/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Forgot password on input label", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/GetInTouch/ContactIcons.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: flex; 3 | align-items: center; 4 | color: var(--mantine-color-white); 5 | } 6 | 7 | .icon { 8 | margin-right: var(--mantine-spacing-md); 9 | background-color: transparent; 10 | } 11 | 12 | .title { 13 | color: var(--mantine-color-blue-0); 14 | } 15 | 16 | .description { 17 | color: var(--mantine-color-white); 18 | } 19 | -------------------------------------------------------------------------------- /lib/GetInTouch/GetInTouch.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { GetInTouch } from './GetInTouch'; 4 | 5 | export default { title: 'GetInTouch' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={GetInTouch} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/GetInTouch/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Get in touch form", 3 | "category": "contact", 4 | "responsive": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 800 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/GetInTouchSimple/GetInTouchSimple.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { GetInTouchSimple } from './GetInTouchSimple'; 4 | 5 | export default { title: 'GetInTouchSimple' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={GetInTouchSimple} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/GetInTouchSimple/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Get in touch form", 3 | "category": "contact", 4 | "responsive": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 620 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/GradientSegmentedControl/GradientSegmentedControl.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6)); 3 | box-shadow: var(--mantine-shadow-md); 4 | border: 1px solid light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-4)); 5 | } 6 | 7 | .indicator { 8 | background-image: linear-gradient( 9 | to right, 10 | var(--mantine-color-pink-filled), 11 | var(--mantine-color-orange-filled) 12 | ); 13 | } 14 | 15 | .control { 16 | &::before { 17 | display: none; 18 | } 19 | } 20 | 21 | .label { 22 | &, 23 | &:hover { 24 | &[data-active] { 25 | color: var(--mantine-color-white); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/GradientSegmentedControl/GradientSegmentedControl.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { GradientSegmentedControl } from './GradientSegmentedControl'; 4 | 5 | export default { title: 'GradientSegmentedControl' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={GradientSegmentedControl} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/GradientSegmentedControl/GradientSegmentedControl.tsx: -------------------------------------------------------------------------------- 1 | import { SegmentedControl } from '@mantine/core'; 2 | import classes from './GradientSegmentedControl.module.css'; 3 | 4 | export function GradientSegmentedControl() { 5 | return ( 6 | <SegmentedControl 7 | radius="xl" 8 | size="md" 9 | data={['All', 'AI/ML', 'C++', 'Rust', 'TypeScript']} 10 | classNames={classes} 11 | /> 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /lib/GradientSegmentedControl/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Gradient segmented control", 3 | "category": "inputs", 4 | "changelog": "september-2022", 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 420 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/GridAsymmetrical/GridAsymmetrical.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { GridAsymmetrical } from './GridAsymmetrical'; 4 | 5 | export default { title: 'GridAsymmetrical' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={GridAsymmetrical} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/GridAsymmetrical/GridAsymmetrical.tsx: -------------------------------------------------------------------------------- 1 | import { Container, Grid, Skeleton } from '@mantine/core'; 2 | 3 | const child = <Skeleton height={140} radius="md" animate={false} />; 4 | 5 | export function GridAsymmetrical() { 6 | return ( 7 | <Container my="md"> 8 | <Grid> 9 | <Grid.Col span={{ base: 12, xs: 4 }}>{child}</Grid.Col> 10 | <Grid.Col span={{ base: 12, xs: 8 }}>{child}</Grid.Col> 11 | <Grid.Col span={{ base: 12, xs: 8 }}>{child}</Grid.Col> 12 | <Grid.Col span={{ base: 12, xs: 4 }}>{child}</Grid.Col> 13 | <Grid.Col span={{ base: 12, xs: 3 }}>{child}</Grid.Col> 14 | <Grid.Col span={{ base: 12, xs: 3 }}>{child}</Grid.Col> 15 | <Grid.Col span={{ base: 12, xs: 6 }}>{child}</Grid.Col> 16 | </Grid> 17 | </Container> 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /lib/GridAsymmetrical/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Grid with asymmetrical columns", 3 | "category": "grids", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/HeaderMegaMenu/HeaderMegaMenu.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeaderMegaMenu } from './HeaderMegaMenu'; 4 | 5 | export default { title: 'HeaderMegaMenu' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeaderMegaMenu} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeaderMegaMenu/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Header with mega menu", 3 | "category": "headers", 4 | "responsive": true, 5 | "changelog": "september-2022", 6 | "canvas": { 7 | "center": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeaderMenu/HeaderMenu.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | height: 56px; 3 | margin-bottom: 120px; 4 | background-color: var(--mantine-color-body); 5 | border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 6 | } 7 | 8 | .inner { 9 | height: 56px; 10 | display: flex; 11 | justify-content: space-between; 12 | align-items: center; 13 | } 14 | 15 | .link { 16 | display: block; 17 | line-height: 1; 18 | padding: 8px 12px; 19 | border-radius: var(--mantine-radius-sm); 20 | text-decoration: none; 21 | color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0)); 22 | font-size: var(--mantine-font-size-sm); 23 | font-weight: 500; 24 | 25 | @mixin hover { 26 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); 27 | } 28 | } 29 | 30 | .linkLabel { 31 | margin-right: 5px; 32 | } 33 | -------------------------------------------------------------------------------- /lib/HeaderMenu/HeaderMenu.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeaderMenu } from './HeaderMenu'; 4 | 5 | export default { title: 'HeaderMenu' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeaderMenu} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeaderMenu/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Header with menus", 3 | "category": "headers", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/HeaderSearch/HeaderSearch.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | height: 56px; 3 | margin-bottom: 120px; 4 | background-color: var(--mantine-color-body); 5 | border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 6 | padding-left: var(--mantine-spacing-md); 7 | padding-right: var(--mantine-spacing-md); 8 | } 9 | 10 | .inner { 11 | height: 56px; 12 | display: flex; 13 | justify-content: space-between; 14 | align-items: center; 15 | } 16 | 17 | .link { 18 | display: block; 19 | line-height: 1; 20 | padding: 8px 12px; 21 | border-radius: var(--mantine-radius-sm); 22 | text-decoration: none; 23 | color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0)); 24 | font-size: var(--mantine-font-size-sm); 25 | font-weight: 500; 26 | 27 | @mixin hover { 28 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/HeaderSearch/HeaderSearch.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeaderSearch } from './HeaderSearch'; 4 | 5 | export default { title: 'HeaderSearch' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeaderSearch} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeaderSearch/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Header with search", 3 | "category": "headers", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/HeaderSimple/HeaderSimple.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | height: 56px; 3 | margin-bottom: 120px; 4 | background-color: var(--mantine-color-body); 5 | border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 6 | } 7 | 8 | .inner { 9 | height: 56px; 10 | display: flex; 11 | justify-content: space-between; 12 | align-items: center; 13 | } 14 | 15 | .link { 16 | display: block; 17 | line-height: 1; 18 | padding: 8px 12px; 19 | border-radius: var(--mantine-radius-sm); 20 | text-decoration: none; 21 | color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0)); 22 | font-size: var(--mantine-font-size-sm); 23 | font-weight: 500; 24 | 25 | @mixin hover { 26 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); 27 | } 28 | 29 | [data-mantine-color-scheme] &[data-active] { 30 | background-color: var(--mantine-color-blue-filled); 31 | color: var(--mantine-color-white); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/HeaderSimple/HeaderSimple.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeaderSimple } from './HeaderSimple'; 4 | 5 | export default { title: 'HeaderSimple' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeaderSimple} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeaderSimple/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Simple header", 3 | "category": "headers", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/HeaderTabs/HeaderTabs.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeaderTabs } from './HeaderTabs'; 4 | 5 | export default { title: 'HeaderTabs' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeaderTabs} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeaderTabs/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Header with tabs", 3 | "category": "headers", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/HeroBullets/HeroBullets.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeroBullets } from './HeroBullets'; 4 | 5 | export default { title: 'HeroBullets' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeroBullets} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeroBullets/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hero with bullets", 3 | "category": "hero", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/HeroContentLeft/HeroContentLeft.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeroContentLeft } from './HeroContentLeft'; 4 | 5 | export default { title: 'HeroContentLeft' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeroContentLeft} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeroContentLeft/HeroContentLeft.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Container, Overlay, Text, Title } from '@mantine/core'; 2 | import classes from './HeroContentLeft.module.css'; 3 | 4 | export function HeroContentLeft() { 5 | return ( 6 | <div className={classes.hero}> 7 | <Overlay 8 | gradient="linear-gradient(180deg, rgba(0, 0, 0, 0.25) 0%, rgba(0, 0, 0, .65) 40%)" 9 | opacity={1} 10 | zIndex={0} 11 | /> 12 | <Container className={classes.container} size="md"> 13 | <Title className={classes.title}>A fully featured React components library</Title> 14 | <Text className={classes.description} size="xl" mt="xl"> 15 | Build fully functional accessible web applications faster than ever – Mantine includes 16 | more than 120 customizable components and hooks to cover you in any situation 17 | </Text> 18 | 19 | <Button variant="gradient" size="xl" radius="xl" className={classes.control}> 20 | Get started 21 | </Button> 22 | </Container> 23 | </div> 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /lib/HeroContentLeft/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hero with content on left", 3 | "category": "hero", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/HeroImageBackground/HeroImageBackground.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeroImageBackground } from './HeroImageBackground'; 4 | 5 | export default { title: 'HeroImageBackground' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeroImageBackground} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeroImageBackground/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hero with background image", 3 | "category": "hero", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/HeroImageRight/HeroImageRight.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeroImageRight } from './HeroImageRight'; 4 | 5 | export default { title: 'HeroImageRight' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeroImageRight} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeroImageRight/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hero with image on the right", 3 | "category": "hero", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/HeroText/HeroText.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeroText } from './HeroText'; 4 | 5 | export default { title: 'HeroText' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeroText} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeroText/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hero section with text", 3 | "category": "hero", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/HeroTitle/HeroTitle.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { HeroTitle } from './HeroTitle'; 4 | 5 | export default { title: 'HeroTitle' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={HeroTitle} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/HeroTitle/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hero section with gradient text", 3 | "category": "hero", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ImageActionBanner/ImageActionBanner.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | height: 240px; 3 | background-size: cover; 4 | background-position: center; 5 | background-image: url(https://images.unsplash.com/photo-1596394516093-501ba68a0ba6?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80); 6 | } 7 | 8 | .content { 9 | position: absolute; 10 | inset: 0; 11 | padding: var(--mantine-spacing-xl); 12 | z-index: 1; 13 | } 14 | 15 | .action { 16 | position: absolute; 17 | bottom: var(--mantine-spacing-xl); 18 | right: var(--mantine-spacing-xl); 19 | } 20 | 21 | .title { 22 | color: var(--mantine-color-white); 23 | margin-bottom: calc(var(--mantine-spacing-xs) / 2); 24 | } 25 | 26 | .description { 27 | color: var(--mantine-color-white); 28 | max-width: 220px; 29 | } 30 | 31 | .overlay { 32 | background-color: transparent; 33 | background-image: linear-gradient( 34 | 105deg, 35 | var(--mantine-color-black) 20%, 36 | #312f2f 50%, 37 | var(--mantine-color-gray-4) 100% 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /lib/ImageActionBanner/ImageActionBanner.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ImageActionBanner } from './ImageActionBanner'; 4 | 5 | export default { title: 'ImageActionBanner' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ImageActionBanner} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ImageActionBanner/ImageActionBanner.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Card, Overlay, Text } from '@mantine/core'; 2 | import classes from './ImageActionBanner.module.css'; 3 | 4 | export function ImageActionBanner() { 5 | return ( 6 | <Card radius="md" className={classes.card}> 7 | <Overlay className={classes.overlay} opacity={0.55} zIndex={0} /> 8 | 9 | <div className={classes.content}> 10 | <Text size="lg" fw={700} className={classes.title}> 11 | Plan & save 12 | </Text> 13 | 14 | <Text size="sm" className={classes.description}> 15 | Save up to 25% at Fifth Season Hotels in Europe, the Middle East, Africa and Asia Pacific 16 | </Text> 17 | 18 | <Button className={classes.action} variant="white" color="dark" size="xs"> 19 | Book now 20 | </Button> 21 | </div> 22 | </Card> 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /lib/ImageActionBanner/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Banner with image and action", 3 | "category": "banners", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 480 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ImageCard/ImageCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ImageCard } from './ImageCard'; 4 | 5 | export default { title: 'ImageCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ImageCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ImageCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with image as background", 3 | "category": "article-cards", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 320 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ImageCheckboxes/ImageCheckboxes.module.css: -------------------------------------------------------------------------------- 1 | .button { 2 | display: flex; 3 | align-items: center; 4 | width: 100%; 5 | transition: 6 | background-color 150ms ease, 7 | border-color 150ms ease; 8 | border-radius: var(--mantine-radius-sm); 9 | padding: var(--mantine-spacing-sm); 10 | border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-8)); 11 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-8)); 12 | 13 | &[data-checked] { 14 | border-color: var(--mantine-color-blue-filled); 15 | background-color: var(--mantine-color-blue-light); 16 | } 17 | } 18 | 19 | .body { 20 | flex: 1; 21 | margin-left: var(--mantine-spacing-md); 22 | } 23 | -------------------------------------------------------------------------------- /lib/ImageCheckboxes/ImageCheckboxes.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ImageCheckboxes } from './ImageCheckboxes'; 4 | 5 | export default { title: 'ImageCheckboxes' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ImageCheckboxes} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ImageCheckboxes/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Checkbox with image", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 1080 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ImageCheckboxes/icons/city.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mantinedev/ui.mantine.dev/620ed0fa88be1e484bddc711af6f0903c037f04e/lib/ImageCheckboxes/icons/city.png -------------------------------------------------------------------------------- /lib/ImageCheckboxes/icons/index.ts: -------------------------------------------------------------------------------- 1 | import city from './city.png'; 2 | import mountain from './mountain.png'; 3 | import sea from './sea.png'; 4 | import winter from './winter.png'; 5 | 6 | export default { 7 | city: city.src, 8 | mountain: mountain.src, 9 | sea: sea.src, 10 | winter: winter.src, 11 | }; 12 | -------------------------------------------------------------------------------- /lib/ImageCheckboxes/icons/mountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mantinedev/ui.mantine.dev/620ed0fa88be1e484bddc711af6f0903c037f04e/lib/ImageCheckboxes/icons/mountain.png -------------------------------------------------------------------------------- /lib/ImageCheckboxes/icons/sea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mantinedev/ui.mantine.dev/620ed0fa88be1e484bddc711af6f0903c037f04e/lib/ImageCheckboxes/icons/sea.png -------------------------------------------------------------------------------- /lib/ImageCheckboxes/icons/winter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mantinedev/ui.mantine.dev/620ed0fa88be1e484bddc711af6f0903c037f04e/lib/ImageCheckboxes/icons/winter.png -------------------------------------------------------------------------------- /lib/InputTooltip/InputTooltip.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { InputTooltip } from './InputTooltip'; 4 | 5 | export default { title: 'InputTooltip' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={InputTooltip} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/InputTooltip/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Inputs with tooltip", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/InputValidation/InputValidation.module.css: -------------------------------------------------------------------------------- 1 | .invalid { 2 | background-color: var(--mantine-color-red-light); 3 | } 4 | 5 | .icon { 6 | color: light-dark(var(--mantine-color-red-6), var(--mantine-color-red-7)); 7 | } 8 | -------------------------------------------------------------------------------- /lib/InputValidation/InputValidation.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { InputValidation } from './InputValidation'; 4 | 5 | export default { title: 'InputValidation' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={InputValidation} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/InputValidation/InputValidation.tsx: -------------------------------------------------------------------------------- 1 | import { IconAlertTriangle } from '@tabler/icons-react'; 2 | import { TextInput } from '@mantine/core'; 3 | import classes from './InputValidation.module.css'; 4 | 5 | export function InputValidation() { 6 | return ( 7 | <TextInput 8 | label="Custom validation styles" 9 | error="Invalid email" 10 | defaultValue="hello!gmail.com" 11 | classNames={{ input: classes.invalid }} 12 | rightSection={<IconAlertTriangle stroke={1.5} size={18} className={classes.icon} />} 13 | /> 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /lib/InputValidation/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Input with custom validation styles", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/InputWithButton/InputWithButton.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { InputWithButton } from './InputWithButton'; 4 | 5 | export default { title: 'InputWithButton' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={InputWithButton} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/InputWithButton/InputWithButton.tsx: -------------------------------------------------------------------------------- 1 | import { IconArrowRight, IconSearch } from '@tabler/icons-react'; 2 | import { ActionIcon, TextInput, TextInputProps, useMantineTheme } from '@mantine/core'; 3 | 4 | export function InputWithButton(props: TextInputProps) { 5 | const theme = useMantineTheme(); 6 | 7 | return ( 8 | <TextInput 9 | radius="xl" 10 | size="md" 11 | placeholder="Search questions" 12 | rightSectionWidth={42} 13 | leftSection={<IconSearch size={18} stroke={1.5} />} 14 | rightSection={ 15 | <ActionIcon size={32} radius="xl" color={theme.primaryColor} variant="filled"> 16 | <IconArrowRight size={18} stroke={1.5} /> 17 | </ActionIcon> 18 | } 19 | {...props} 20 | /> 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /lib/InputWithButton/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Input with contained button", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 520 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/LanguagePicker/LanguagePicker.module.css: -------------------------------------------------------------------------------- 1 | .control { 2 | width: 200px; 3 | display: flex; 4 | justify-content: space-between; 5 | align-items: center; 6 | padding: var(--mantine-spacing-xs) var(--mantine-spacing-md); 7 | border-radius: var(--mantine-radius-md); 8 | border: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-6)); 9 | transition: background-color 150ms ease; 10 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6)); 11 | 12 | &[data-expanded] { 13 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5)); 14 | } 15 | 16 | @mixin hover { 17 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5)); 18 | } 19 | } 20 | 21 | .label { 22 | font-weight: 500; 23 | font-size: var(--mantine-font-size-sm); 24 | } 25 | 26 | .icon { 27 | transition: transform 150ms ease; 28 | transform: rotate(0deg); 29 | 30 | [data-expanded] & { 31 | transform: rotate(180deg); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/LanguagePicker/LanguagePicker.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { LanguagePicker } from './LanguagePicker'; 4 | 5 | export default { title: 'LanguagePicker' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={LanguagePicker} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/LanguagePicker/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Language picker", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 220 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/LanguagePicker/images/english.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mantinedev/ui.mantine.dev/620ed0fa88be1e484bddc711af6f0903c037f04e/lib/LanguagePicker/images/english.png -------------------------------------------------------------------------------- /lib/LanguagePicker/images/french.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mantinedev/ui.mantine.dev/620ed0fa88be1e484bddc711af6f0903c037f04e/lib/LanguagePicker/images/french.png -------------------------------------------------------------------------------- /lib/LanguagePicker/images/german.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mantinedev/ui.mantine.dev/620ed0fa88be1e484bddc711af6f0903c037f04e/lib/LanguagePicker/images/german.png -------------------------------------------------------------------------------- /lib/LanguagePicker/images/index.ts: -------------------------------------------------------------------------------- 1 | import english from './english.png'; 2 | import french from './french.png'; 3 | import german from './german.png'; 4 | import italian from './italian.png'; 5 | import polish from './polish.png'; 6 | 7 | export default { 8 | english: english.src, 9 | french: french.src, 10 | german: german.src, 11 | italian: italian.src, 12 | polish: polish.src, 13 | }; 14 | -------------------------------------------------------------------------------- /lib/LanguagePicker/images/italian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mantinedev/ui.mantine.dev/620ed0fa88be1e484bddc711af6f0903c037f04e/lib/LanguagePicker/images/italian.png -------------------------------------------------------------------------------- /lib/LanguagePicker/images/polish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mantinedev/ui.mantine.dev/620ed0fa88be1e484bddc711af6f0903c037f04e/lib/LanguagePicker/images/polish.png -------------------------------------------------------------------------------- /lib/LeadGrid/LeadGrid.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { LeadGrid } from './LeadGrid'; 4 | 5 | export default { title: 'LeadGrid' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={LeadGrid} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/LeadGrid/LeadGrid.tsx: -------------------------------------------------------------------------------- 1 | import { Container, Grid, SimpleGrid, Skeleton } from '@mantine/core'; 2 | 3 | const PRIMARY_COL_HEIGHT = '300px'; 4 | 5 | export function LeadGrid() { 6 | const SECONDARY_COL_HEIGHT = `calc(${PRIMARY_COL_HEIGHT} / 2 - var(--mantine-spacing-md) / 2)`; 7 | 8 | return ( 9 | <Container my="md"> 10 | <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md"> 11 | <Skeleton height={PRIMARY_COL_HEIGHT} radius="md" animate={false} /> 12 | <Grid gutter="md"> 13 | <Grid.Col> 14 | <Skeleton height={SECONDARY_COL_HEIGHT} radius="md" animate={false} /> 15 | </Grid.Col> 16 | <Grid.Col span={6}> 17 | <Skeleton height={SECONDARY_COL_HEIGHT} radius="md" animate={false} /> 18 | </Grid.Col> 19 | <Grid.Col span={6}> 20 | <Skeleton height={SECONDARY_COL_HEIGHT} radius="md" animate={false} /> 21 | </Grid.Col> 22 | </Grid> 23 | </SimpleGrid> 24 | </Container> 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /lib/LeadGrid/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Grid with leading item", 3 | "category": "grids", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/NavbarLinksGroup/NavbarLinksGroup.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NavbarLinksGroup } from './NavbarLinksGroup'; 4 | 5 | export default { title: 'NavbarLinksGroup' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NavbarLinksGroup} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NavbarLinksGroup/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Collapsible links group", 3 | "category": "navbars", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 320 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/NavbarMinimal/NavbarMinimal.module.css: -------------------------------------------------------------------------------- 1 | .navbar { 2 | width: 80px; 3 | height: 750px; 4 | padding: var(--mantine-spacing-md); 5 | display: flex; 6 | flex-direction: column; 7 | border-right: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 8 | } 9 | 10 | .navbarMain { 11 | flex: 1; 12 | margin-top: 50px; 13 | } 14 | 15 | .link { 16 | width: 50px; 17 | height: 50px; 18 | border-radius: var(--mantine-radius-md); 19 | display: flex; 20 | align-items: center; 21 | justify-content: center; 22 | color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0)); 23 | 24 | &:hover { 25 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5)); 26 | } 27 | 28 | &[data-active] { 29 | &, 30 | &:hover { 31 | background-color: var(--mantine-color-blue-light); 32 | color: var(--mantine-color-blue-light-color); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/NavbarMinimal/NavbarMinimal.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NavbarMinimal } from './NavbarMinimal'; 4 | 5 | export default { title: 'NavbarMinimal' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NavbarMinimal} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NavbarMinimal/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Navbar with tooltips", 3 | "category": "navbars", 4 | "canvas": { 5 | "center": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/NavbarMinimalColored/NavbarMinimalColored.module.css: -------------------------------------------------------------------------------- 1 | .navbar { 2 | width: 80px; 3 | height: 750px; 4 | padding: var(--mantine-spacing-md); 5 | display: flex; 6 | flex-direction: column; 7 | background-color: var(--mantine-color-blue-filled); 8 | } 9 | 10 | .navbarMain { 11 | flex: 1; 12 | margin-top: 50px; 13 | } 14 | 15 | .link { 16 | width: 50px; 17 | height: 50px; 18 | border-radius: var(--mantine-radius-md); 19 | display: flex; 20 | align-items: center; 21 | justify-content: center; 22 | color: var(--mantine-color-white); 23 | 24 | &:hover { 25 | background-color: var(--mantine-color-blue-7); 26 | } 27 | 28 | &[data-active] { 29 | &, 30 | &:hover { 31 | box-shadow: var(--mantine-shadow-sm); 32 | background-color: var(--mantine-color-white); 33 | color: var(--mantine-color-blue-6); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/NavbarMinimalColored/NavbarMinimalColored.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NavbarMinimalColored } from './NavbarMinimalColored'; 4 | 5 | export default { title: 'NavbarMinimalColored' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NavbarMinimalColored} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NavbarMinimalColored/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Navbar with tooltips", 3 | "category": "navbars", 4 | "canvas": { 5 | "center": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/NavbarNested/NavbarNested.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NavbarNested } from './NavbarNested'; 4 | 5 | export default { title: 'NavbarNested' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NavbarNested} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NavbarNested/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Navbar with nested links", 3 | "category": "navbars", 4 | "canvas": { 5 | "center": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/NavbarSearch/NavbarSearch.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NavbarSearch } from './NavbarSearch'; 4 | 5 | export default { title: 'NavbarSearch' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NavbarSearch} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NavbarSearch/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Navbar with search", 3 | "category": "navbars", 4 | "canvas": { 5 | "center": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/NavbarSegmented/NavbarSegmented.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NavbarSegmented } from './NavbarSegmented'; 4 | 5 | export default { title: 'NavbarSegmented' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NavbarSegmented} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NavbarSegmented/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Navbar with SegmentedControl", 3 | "category": "navbars", 4 | "canvas": { 5 | "center": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/NavbarSimple/NavbarSimple.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NavbarSimple } from './NavbarSimple'; 4 | 5 | export default { title: 'NavbarSimple' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NavbarSimple} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NavbarSimple/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Simple navbar", 3 | "category": "navbars", 4 | "canvas": { 5 | "center": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/NavbarSimpleColored/NavbarSimpleColored.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NavbarSimpleColored } from './NavbarSimpleColored'; 4 | 5 | export default { title: 'NavbarSimpleColored' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NavbarSimpleColored} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NavbarSimpleColored/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Simple navbar", 3 | "category": "navbars", 4 | "canvas": { 5 | "center": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/NotFoundImage/NotFoundImage.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | padding-top: 80px; 3 | padding-bottom: 80px; 4 | } 5 | 6 | .title { 7 | font-weight: 500; 8 | font-size: 34px; 9 | margin-bottom: var(--mantine-spacing-md); 10 | font-family: Outfit, var(--mantine-font-family); 11 | 12 | @media (max-width: $mantine-breakpoint-sm) { 13 | font-size: 32px; 14 | } 15 | } 16 | 17 | .control { 18 | @media (max-width: $mantine-breakpoint-sm) { 19 | width: 100%; 20 | } 21 | } 22 | 23 | .mobileImage { 24 | @media (min-width: 48em) { 25 | display: none; 26 | } 27 | } 28 | 29 | .desktopImage { 30 | @media (max-width: 47.99em) { 31 | display: none; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/NotFoundImage/NotFoundImage.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NotFoundImage } from './NotFoundImage'; 4 | 5 | export default { title: 'NotFoundImage' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NotFoundImage} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NotFoundImage/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "404 page with image", 3 | "category": "error-pages", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/NotFoundTitle/NotFoundTitle.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | padding-top: 80px; 3 | padding-bottom: 80px; 4 | } 5 | 6 | .label { 7 | text-align: center; 8 | font-weight: 500; 9 | font-size: 38px; 10 | line-height: 1; 11 | margin-bottom: calc(1.5 * var(--mantine-spacing-xl)); 12 | color: var(--mantine-color-gray-2); 13 | 14 | @media (max-width: $mantine-breakpoint-sm) { 15 | font-size: 32px; 16 | } 17 | } 18 | 19 | .description { 20 | max-width: 500px; 21 | margin: auto; 22 | margin-top: var(--mantine-spacing-xl); 23 | margin-bottom: calc(1.5 * var(--mantine-spacing-xl)); 24 | } 25 | 26 | .title { 27 | font-family: 'Outfit', var(--mantine-font-family); 28 | text-align: center; 29 | font-weight: 500; 30 | font-size: 38px; 31 | 32 | @media (max-width: $mantine-breakpoint-sm) { 33 | font-size: 32px; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/NotFoundTitle/NotFoundTitle.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NotFoundTitle } from './NotFoundTitle'; 4 | 5 | export default { title: 'NotFoundTitle' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NotFoundTitle} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NotFoundTitle/NotFoundTitle.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Container, Group, Text, Title } from '@mantine/core'; 2 | import classes from './NotFoundTitle.module.css'; 3 | 4 | export function NotFoundTitle() { 5 | return ( 6 | <Container className={classes.root}> 7 | <div className={classes.label}>404</div> 8 | <Title className={classes.title}>You have found a secret place.</Title> 9 | <Text c="dimmed" size="lg" ta="center" className={classes.description}> 10 | Unfortunately, this is only a 404 page. You may have mistyped the address, or the page has 11 | been moved to another URL. 12 | </Text> 13 | <Group justify="center"> 14 | <Button variant="subtle" size="md"> 15 | Take me back to home page 16 | </Button> 17 | </Group> 18 | </Container> 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /lib/NotFoundTitle/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "404 page", 3 | "category": "error-pages", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/NothingFoundBackground/NothingFoundBackground.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | padding-top: 80px; 3 | padding-bottom: 80px; 4 | } 5 | 6 | .inner { 7 | position: relative; 8 | } 9 | 10 | .image { 11 | position: absolute; 12 | inset: 0; 13 | opacity: 0.75; 14 | color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); 15 | } 16 | 17 | .content { 18 | padding-top: 220px; 19 | position: relative; 20 | z-index: 1; 21 | 22 | @media (max-width: $mantine-breakpoint-sm) { 23 | padding-top: 120px; 24 | } 25 | } 26 | 27 | .title { 28 | font-family: Outfit, var(--mantine-font-family); 29 | text-align: center; 30 | font-weight: 500; 31 | font-size: 38px; 32 | 33 | @media (max-width: $mantine-breakpoint-sm) { 34 | font-size: 32px; 35 | } 36 | } 37 | 38 | .description { 39 | max-width: 540px; 40 | margin: auto; 41 | margin-top: var(--mantine-spacing-xl); 42 | margin-bottom: calc(var(--mantine-spacing-xl) * 1.5); 43 | } 44 | -------------------------------------------------------------------------------- /lib/NothingFoundBackground/NothingFoundBackground.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { NothingFoundBackground } from './NothingFoundBackground'; 4 | 5 | export default { title: 'NothingFoundBackground' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={NothingFoundBackground} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/NothingFoundBackground/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "404 as background image", 3 | "category": "error-pages", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/PasswordStrength/PasswordStrength.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { PasswordStrength } from './PasswordStrength'; 4 | 5 | export default { title: 'PasswordStrength' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={PasswordStrength} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/PasswordStrength/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Password with strength meter", 3 | "category": "inputs", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 320 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ProgressCard/ProgressCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ProgressCard } from './ProgressCard'; 4 | 5 | export default { title: 'ProgressCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ProgressCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ProgressCard/ProgressCard.tsx: -------------------------------------------------------------------------------- 1 | import { Card, Progress, Text } from '@mantine/core'; 2 | 3 | export function ProgressCard() { 4 | return ( 5 | <Card withBorder radius="md" padding="xl" bg="var(--mantine-color-body)"> 6 | <Text fz="xs" tt="uppercase" fw={700} c="dimmed"> 7 | Monthly goal 8 | </Text> 9 | <Text fz="lg" fw={500}> 10 | $5.431 / $10.000 11 | </Text> 12 | <Progress value={54.31} mt="md" size="lg" radius="xl" /> 13 | </Card> 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /lib/ProgressCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Progress card", 3 | "category": "stats", 4 | "changelog": "september-2022", 5 | "dimmed": true, 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 380 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/ProgressCardColored/ProgressCardColored.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: var(--mantine-color-blue-filled); 3 | } 4 | 5 | .title { 6 | color: var(--mantine-color-white); 7 | opacity: 0.65; 8 | } 9 | 10 | .stats { 11 | color: var(--mantine-color-white); 12 | } 13 | 14 | .progressSection { 15 | background-color: var(--mantine-color-white); 16 | } 17 | 18 | .progressTrack { 19 | background-color: var(--mantine-color-blue-3); 20 | } 21 | -------------------------------------------------------------------------------- /lib/ProgressCardColored/ProgressCardColored.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ProgressCardColored } from './ProgressCardColored'; 4 | 5 | export default { title: 'ProgressCardColored' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ProgressCardColored} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ProgressCardColored/ProgressCardColored.tsx: -------------------------------------------------------------------------------- 1 | import { Card, Progress, Text } from '@mantine/core'; 2 | import classes from './ProgressCardColored.module.css'; 3 | 4 | export function ProgressCardColored() { 5 | return ( 6 | <Card withBorder radius="md" p="xl" className={classes.card}> 7 | <Text fz="xs" tt="uppercase" fw={700} className={classes.title}> 8 | Monthly goal 9 | </Text> 10 | <Text fz="lg" fw={500} className={classes.stats}> 11 | $5.431 / $10.000 12 | </Text> 13 | <Progress 14 | value={54.31} 15 | mt="md" 16 | size="lg" 17 | radius="xl" 18 | classNames={{ 19 | root: classes.progressTrack, 20 | section: classes.progressSection, 21 | }} 22 | /> 23 | </Card> 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /lib/ProgressCardColored/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Progress card with color", 3 | "category": "stats", 4 | "changelog": "september-2022", 5 | "dimmed": true, 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 380 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/ServerError/ServerError.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | padding-top: 80px; 3 | padding-bottom: 120px; 4 | background-color: var(--mantine-color-blue-filled); 5 | } 6 | 7 | .label { 8 | text-align: center; 9 | font-weight: 500; 10 | font-size: 220px; 11 | line-height: 1; 12 | margin-bottom: calc(var(--mantine-spacing-xl) * 1.5); 13 | color: var(--mantine-color-blue-3); 14 | 15 | @media (max-width: $mantine-breakpoint-sm) { 16 | font-size: 120px; 17 | } 18 | } 19 | 20 | .title { 21 | font-family: Outfit, var(--mantine-font-family); 22 | text-align: center; 23 | font-weight: 500; 24 | font-size: 38px; 25 | color: var(--mantine-color-white); 26 | 27 | @media (max-width: $mantine-breakpoint-sm) { 28 | font-size: 32px; 29 | } 30 | } 31 | 32 | .description { 33 | max-width: 540px; 34 | margin: auto; 35 | margin-top: var(--mantine-spacing-xl); 36 | margin-bottom: calc(var(--mantine-spacing-xl) * 1.5); 37 | color: var(--mantine-color-blue-1); 38 | } 39 | -------------------------------------------------------------------------------- /lib/ServerError/ServerError.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ServerError } from './ServerError'; 4 | 5 | export default { title: 'ServerError' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ServerError} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ServerError/ServerError.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Container, Group, Text, Title } from '@mantine/core'; 2 | import classes from './ServerError.module.css'; 3 | 4 | export function ServerError() { 5 | return ( 6 | <div className={classes.root}> 7 | <Container> 8 | <div className={classes.label}>500</div> 9 | <Title className={classes.title}>Something bad just happened...</Title> 10 | <Text size="lg" ta="center" className={classes.description}> 11 | Our servers could not handle your request. Don't worry, our development team was 12 | already notified. Try refreshing the page. 13 | </Text> 14 | <Group justify="center"> 15 | <Button variant="white" size="md"> 16 | Refresh the page 17 | </Button> 18 | </Group> 19 | </Container> 20 | </div> 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /lib/ServerError/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "500 page", 3 | "category": "error-pages", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/ServerOverload/ServerOverload.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { ServerOverload } from './ServerOverload'; 4 | 5 | export default { title: 'ServerOverload' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={ServerOverload} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/ServerOverload/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "503 page", 3 | "category": "error-pages", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/SliderHover/SliderHover.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { SliderHover } from './SliderHover'; 4 | 5 | export default { title: 'SliderHover' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={SliderHover} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/SliderHover/SliderHover.tsx: -------------------------------------------------------------------------------- 1 | import { Slider } from '@mantine/core'; 2 | import { useHover } from '@mantine/hooks'; 3 | 4 | export function SliderHover() { 5 | const { hovered, ref } = useHover(); 6 | 7 | return ( 8 | <Slider 9 | defaultValue={40} 10 | min={10} 11 | max={90} 12 | ref={ref} 13 | label={null} 14 | styles={{ 15 | thumb: { 16 | transition: 'opacity 150ms ease', 17 | opacity: hovered ? 1 : 0, 18 | }, 19 | }} 20 | /> 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /lib/SliderHover/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Slider with thumb visible on hover", 3 | "category": "sliders", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/SliderIcon/SliderIcon.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { SliderIcon } from './SliderIcon'; 4 | 5 | export default { title: 'SliderIcon' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={SliderIcon} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/SliderIcon/SliderIcon.tsx: -------------------------------------------------------------------------------- 1 | import { IconHeart, IconHeartBroken } from '@tabler/icons-react'; 2 | import { RangeSlider, Slider } from '@mantine/core'; 3 | 4 | const styles = { thumb: { borderWidth: 2, height: 26, width: 26, padding: 3 } }; 5 | 6 | export function SliderIcon() { 7 | return ( 8 | <> 9 | <Slider 10 | thumbChildren={<IconHeart size={16} stroke={1.5} />} 11 | color="red" 12 | label={null} 13 | defaultValue={40} 14 | styles={styles} 15 | /> 16 | 17 | <RangeSlider 18 | mt="xl" 19 | styles={styles} 20 | color="red" 21 | label={null} 22 | defaultValue={[20, 60]} 23 | thumbChildren={[ 24 | <IconHeart size={16} stroke={1.5} key="1" />, 25 | <IconHeartBroken size={16} stroke={1.5} key="2" />, 26 | ]} 27 | /> 28 | </> 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /lib/SliderIcon/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Slider with icon thumb", 3 | "category": "sliders", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/SliderInput/SliderInput.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: relative; 3 | } 4 | 5 | .input { 6 | height: auto; 7 | padding-top: 22px; 8 | padding-bottom: 3px; 9 | border-bottom-right-radius: 0; 10 | border-bottom-left-radius: 0; 11 | } 12 | 13 | .label { 14 | position: absolute; 15 | pointer-events: none; 16 | padding-left: var(--mantine-spacing-sm); 17 | padding-top: calc(var(--mantine-spacing-sm) / 2); 18 | z-index: 1; 19 | } 20 | 21 | .slider { 22 | position: absolute; 23 | width: 100%; 24 | bottom: -1px; 25 | } 26 | 27 | .thumb { 28 | width: 16px; 29 | height: 16px; 30 | } 31 | 32 | .track { 33 | &::before { 34 | background-color: (var(--mantine-color-gray-4), var(--mantine-color-dark-3)); 35 | } 36 | } 37 | 38 | .bar { 39 | border-radius: 0; 40 | } 41 | -------------------------------------------------------------------------------- /lib/SliderInput/SliderInput.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { SliderInput } from './SliderInput'; 4 | 5 | export default { title: 'SliderInput' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={SliderInput} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/SliderInput/SliderInput.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import { NumberInput, Slider } from '@mantine/core'; 3 | import classes from './SliderInput.module.css'; 4 | 5 | export function SliderInput() { 6 | const [value, setValue] = useState<number | string>(2200); 7 | return ( 8 | <div className={classes.wrapper}> 9 | <NumberInput 10 | value={value} 11 | onChange={setValue} 12 | label="Your daily kcal consumption" 13 | placeholder="2200 is an average value" 14 | step={50} 15 | min={0} 16 | max={8000} 17 | hideControls 18 | classNames={{ input: classes.input, label: classes.label }} 19 | /> 20 | <Slider 21 | max={8000} 22 | step={50} 23 | min={0} 24 | label={null} 25 | value={typeof value === 'string' ? 0 : value} 26 | onChange={setValue} 27 | size={2} 28 | className={classes.slider} 29 | classNames={classes} 30 | /> 31 | </div> 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /lib/SliderInput/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "NumberInput with slider", 3 | "category": "sliders", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/SliderLabel/SliderLabel.module.css: -------------------------------------------------------------------------------- 1 | .label { 2 | top: 0; 3 | height: 28px; 4 | line-height: 28px; 5 | width: 34px; 6 | padding: 0; 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | font-weight: 700; 11 | background-color: transparent; 12 | } 13 | 14 | .thumb { 15 | background-color: var(--mantine-color-blue-6); 16 | height: 28px; 17 | width: 34px; 18 | border: none; 19 | } 20 | -------------------------------------------------------------------------------- /lib/SliderLabel/SliderLabel.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { SliderLabel } from './SliderLabel'; 4 | 5 | export default { title: 'SliderLabel' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={SliderLabel} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/SliderLabel/SliderLabel.tsx: -------------------------------------------------------------------------------- 1 | import { RangeSlider } from '@mantine/core'; 2 | import classes from './SliderLabel.module.css'; 3 | 4 | export function SliderLabel() { 5 | return <RangeSlider labelAlwaysOn defaultValue={[20, 60]} classNames={classes} />; 6 | } 7 | -------------------------------------------------------------------------------- /lib/SliderLabel/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Range slider with labels", 3 | "category": "sliders", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/SliderMarks/SliderMarks.module.css: -------------------------------------------------------------------------------- 1 | .mark { 2 | display: flex; 3 | } 4 | 5 | .thumb { 6 | width: 16px; 7 | height: 28px; 8 | background-color: var(--mantine-color-white); 9 | color: var(--mantine-color-gray-5); 10 | border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-2)); 11 | } 12 | -------------------------------------------------------------------------------- /lib/SliderMarks/SliderMarks.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { SliderMarks } from './SliderMarks'; 4 | 5 | export default { title: 'SliderMarks' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={SliderMarks} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/SliderMarks/SliderMarks.tsx: -------------------------------------------------------------------------------- 1 | import { IconGripVertical, IconPoint } from '@tabler/icons-react'; 2 | import { RangeSlider } from '@mantine/core'; 3 | import classes from './SliderMarks.module.css'; 4 | 5 | const point = <IconPoint size={10} style={{ marginTop: 6 }} stroke={1.5} />; 6 | 7 | export function SliderMarks() { 8 | return ( 9 | <RangeSlider 10 | mt="xl" 11 | mb="xl" 12 | classNames={classes} 13 | defaultValue={[30, 60]} 14 | thumbChildren={<IconGripVertical size={20} stroke={1.5} />} 15 | marks={[ 16 | { value: 0, label: '0' }, 17 | { value: 12.5, label: point }, 18 | { value: 25, label: '25' }, 19 | { value: 37.5, label: point }, 20 | { value: 50, label: '50' }, 21 | { value: 62.5, label: point }, 22 | { value: 75, label: '75' }, 23 | { value: 87.5, label: point }, 24 | { value: 100, label: '100' }, 25 | ]} 26 | /> 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /lib/SliderMarks/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Slider with marks", 3 | "category": "sliders", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/SliderWhite/SliderWhite.module.css: -------------------------------------------------------------------------------- 1 | .thumb { 2 | border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-2)); 3 | width: 28px; 4 | height: 22px; 5 | color: var(--mantine-color-gray-5); 6 | background-color: var(--mantine-color-white); 7 | border-radius: var(--mantine-radius-sm); 8 | } 9 | -------------------------------------------------------------------------------- /lib/SliderWhite/SliderWhite.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { SliderWhite } from './SliderWhite'; 4 | 5 | export default { title: 'SliderWhite' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={SliderWhite} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/SliderWhite/SliderWhite.tsx: -------------------------------------------------------------------------------- 1 | import { IconGripHorizontal } from '@tabler/icons-react'; 2 | import { Slider } from '@mantine/core'; 3 | import classes from './SliderWhite.module.css'; 4 | 5 | export function SliderWhite() { 6 | return ( 7 | <Slider 8 | classNames={classes} 9 | thumbChildren={<IconGripHorizontal size={20} stroke={1.5} />} 10 | defaultValue={40} 11 | label={null} 12 | /> 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /lib/SliderWhite/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Slider with white thumb", 3 | "category": "sliders", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 420 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/SocialButtons/FacebookIcon.tsx: -------------------------------------------------------------------------------- 1 | export function FacebookIcon(props: React.ComponentProps<'svg'>) { 2 | return ( 3 | <svg 4 | aria-hidden="true" 5 | focusable="false" 6 | data-prefix="fab" 7 | data-icon="facebook" 8 | className="svg-inline--fa fa-facebook" 9 | role="img" 10 | xmlns="http://www.w3.org/2000/svg" 11 | viewBox="0 0 512 512" 12 | style={{ width: 14, height: 14 }} 13 | {...props} 14 | > 15 | <path 16 | fill="currentColor" 17 | d="M504 256C504 119 393 8 256 8S8 119 8 256c0 123.8 90.69 226.4 209.3 245V327.7h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.28c-30.8 0-40.41 19.12-40.41 38.73V256h68.78l-11 71.69h-57.78V501C413.3 482.4 504 379.8 504 256z" 18 | /> 19 | </svg> 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /lib/SocialButtons/SocialButtons.module.css: -------------------------------------------------------------------------------- 1 | .facebookButton { 2 | background-color: #4267b2; 3 | color: #fff; 4 | 5 | @mixin hover { 6 | background-color: #3a5a9b; 7 | } 8 | } 9 | 10 | .discordButton { 11 | background-color: #5865f2; 12 | color: #fff; 13 | 14 | @mixin hover { 15 | background-color: #525ee0; 16 | } 17 | } 18 | 19 | /* backgroundColor: theme.colors.dark[theme.colorScheme === 'dark' ? 9 : 6], 20 | color: '#fff', 21 | '&:hover': { 22 | backgroundColor: theme.colors.dark[theme.colorScheme === 'dark' ? 9 : 6], 23 | }, */ 24 | 25 | .githubButton { 26 | background-color: light-dark(var(--mantine-color-dark-6), var(--mantine-color-dark-9)); 27 | color: #fff; 28 | 29 | @mixin hover { 30 | background-color: light-dark(var(--mantine-color-dark-6), var(--mantine-color-dark-9)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/SocialButtons/SocialButtons.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { SocialButtons } from './SocialButtons'; 4 | 5 | export default { title: 'SocialButtons' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={SocialButtons} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/SocialButtons/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Social buttons", 3 | "category": "buttons", 4 | "canvas": { 5 | "center": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/SplitButton/SplitButton.module.css: -------------------------------------------------------------------------------- 1 | .button { 2 | border-top-right-radius: 0; 3 | border-bottom-right-radius: 0; 4 | } 5 | 6 | .menuControl { 7 | border-top-left-radius: 0; 8 | border-bottom-left-radius: 0; 9 | border: 0; 10 | border-left: 1px solid var(--mantine-color-body); 11 | } 12 | -------------------------------------------------------------------------------- /lib/SplitButton/SplitButton.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { SplitButton } from './SplitButton'; 4 | 5 | export default { title: 'SplitButton' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={SplitButton} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/SplitButton/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Split button", 3 | "category": "buttons", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 120 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/StatsCard/StatsCard.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | position: relative; 3 | overflow: visible; 4 | padding: var(--mantine-spacing-xl); 5 | padding-top: calc(var(--mantine-spacing-xl) * 1.5 + 20px); 6 | } 7 | 8 | .icon { 9 | position: absolute; 10 | top: -20px; 11 | left: calc(50% - 30px); 12 | } 13 | 14 | .title { 15 | font-family: Outfit, var(--mantine-font-family); 16 | line-height: 1; 17 | } 18 | -------------------------------------------------------------------------------- /lib/StatsCard/StatsCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { StatsCard } from './StatsCard'; 4 | 5 | export default { title: 'StatsCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={StatsCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with progress", 3 | "category": "stats", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 320 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsControls/StatsControls.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { StatsControls } from './StatsControls'; 4 | 5 | export default { title: 'StatsControls' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={StatsControls} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsControls/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Stats with controls", 3 | "category": "stats", 4 | "responsive": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 500 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsGrid/StatsGrid.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | padding: calc(var(--mantine-spacing-xl) * 1.5); 3 | } 4 | 5 | .value { 6 | font-size: 24px; 7 | font-weight: 700; 8 | line-height: 1; 9 | } 10 | 11 | .diff { 12 | line-height: 1; 13 | display: flex; 14 | align-items: center; 15 | } 16 | 17 | .icon { 18 | color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-3)); 19 | } 20 | 21 | .title { 22 | font-weight: 700; 23 | text-transform: uppercase; 24 | } 25 | -------------------------------------------------------------------------------- /lib/StatsGrid/StatsGrid.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { StatsGrid } from './StatsGrid'; 4 | 5 | export default { title: 'StatsGrid' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={StatsGrid} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsGrid/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Stats grid", 3 | "category": "stats", 4 | "responsive": true, 5 | "dimmed": true, 6 | "canvas": { 7 | "center": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsGridIcons/StatsGridIcons.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | padding: calc(var(--mantine-spacing-xl) * 1.5); 3 | } 4 | 5 | .label { 6 | font-family: Outfit, var(--mantine-font-family); 7 | } 8 | -------------------------------------------------------------------------------- /lib/StatsGridIcons/StatsGridIcons.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { StatsGridIcons } from './StatsGridIcons'; 4 | 5 | export default { title: 'StatsGridIcons' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={StatsGridIcons} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsGridIcons/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Stats grid with diff icons", 3 | "category": "stats", 4 | "responsive": true, 5 | "dimmed": true, 6 | "canvas": { 7 | "center": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsGroup/StatsGroup.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { StatsGroup } from './StatsGroup'; 4 | 5 | export default { title: 'StatsGroup' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={StatsGroup} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsGroup/StatsGroup.tsx: -------------------------------------------------------------------------------- 1 | import { Text } from '@mantine/core'; 2 | import classes from './StatsGroup.module.css'; 3 | 4 | const data = [ 5 | { 6 | title: 'Page views', 7 | stats: '456,133', 8 | description: '24% more than in the same month last year, 33% more that two years ago', 9 | }, 10 | { 11 | title: 'New users', 12 | stats: '2,175', 13 | description: '13% less compared to last month, new user engagement up by 6%', 14 | }, 15 | { 16 | title: 'Completed orders', 17 | stats: '1,994', 18 | description: '1994 orders were completed this month, 97% satisfaction rate', 19 | }, 20 | ]; 21 | 22 | export function StatsGroup() { 23 | const stats = data.map((stat) => ( 24 | <div key={stat.title} className={classes.stat}> 25 | <Text className={classes.count}>{stat.stats}</Text> 26 | <Text className={classes.title}>{stat.title}</Text> 27 | <Text className={classes.description}>{stat.description}</Text> 28 | </div> 29 | )); 30 | return <div className={classes.root}>{stats}</div>; 31 | } 32 | -------------------------------------------------------------------------------- /lib/StatsGroup/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Grouped stats", 3 | "category": "stats", 4 | "responsive": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 920 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsRing/StatsRing.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { StatsRing } from './StatsRing'; 4 | 5 | export default { title: 'StatsRing' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={StatsRing} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsRing/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Stats with ring progress", 3 | "category": "stats", 4 | "responsive": true, 5 | "dimmed": true, 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 840 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/StatsRingCard/StatsRingCard.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: var(--mantine-color-body); 3 | } 4 | 5 | .label { 6 | font-family: Outfit, var(--mantine-font-family); 7 | font-weight: 700; 8 | line-height: 1; 9 | } 10 | 11 | .lead { 12 | font-family: Outfit, var(--mantine-font-family); 13 | font-weight: 700; 14 | font-size: 22px; 15 | line-height: 1; 16 | } 17 | 18 | .inner { 19 | display: flex; 20 | 21 | @media (max-width: $mantine-breakpoint-xs) { 22 | flex-direction: column; 23 | } 24 | } 25 | 26 | .ring { 27 | flex: 1; 28 | display: flex; 29 | justify-content: flex-end; 30 | 31 | @media (max-width: $mantine-breakpoint-xs) { 32 | justify-content: center; 33 | margin-top: var(--mantine-spacing-md); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/StatsRingCard/StatsRingCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { StatsRingCard } from './StatsRingCard'; 4 | 5 | export default { title: 'StatsRingCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={StatsRingCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsRingCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Stats card with progress", 3 | "category": "app-cards", 4 | "responsive": true, 5 | "dimmed": true, 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 420 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/StatsSegments/StatsSegments.module.css: -------------------------------------------------------------------------------- 1 | .progressLabel { 2 | font-family: Outfit, var(--mantine-font-family); 3 | line-height: 1; 4 | font-size: var(--mantine-font-size-sm); 5 | } 6 | 7 | .stat { 8 | border-bottom: 3px solid; 9 | padding-bottom: 5px; 10 | } 11 | 12 | .statCount { 13 | font-family: Outfit, var(--mantine-font-family); 14 | line-height: 1.3; 15 | } 16 | 17 | .diff { 18 | font-family: Outfit, var(--mantine-font-family); 19 | display: flex; 20 | align-items: center; 21 | } 22 | 23 | .icon { 24 | color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-3)); 25 | } 26 | -------------------------------------------------------------------------------- /lib/StatsSegments/StatsSegments.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { StatsSegments } from './StatsSegments'; 4 | 5 | export default { title: 'StatsSegments' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={StatsSegments} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/StatsSegments/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Stats with segments", 3 | "category": "stats", 4 | "responsive": true, 5 | "dimmed": true, 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 440 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/Subgrid/Subgrid.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { Subgrid } from './Subgrid'; 4 | 5 | export default { title: 'Subgrid' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={Subgrid} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/Subgrid/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Grid with vertical items", 3 | "category": "grids", 4 | "responsive": true, 5 | "canvas": { 6 | "center": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/SwitchesCard/SwitchesCard.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: var(--mantine-color-body); 3 | } 4 | 5 | .item { 6 | & + & { 7 | padding-top: var(--mantine-spacing-sm); 8 | margin-top: var(--mantine-spacing-sm); 9 | border-top: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-4)); 10 | } 11 | } 12 | 13 | .switch { 14 | & * { 15 | cursor: pointer; 16 | } 17 | } 18 | 19 | .title { 20 | line-height: 1; 21 | } 22 | -------------------------------------------------------------------------------- /lib/SwitchesCard/SwitchesCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { SwitchesCard } from './SwitchesCard'; 4 | 5 | export default { title: 'SwitchesCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={SwitchesCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/SwitchesCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Card with switches", 3 | "category": "app-cards", 4 | "responsive": true, 5 | "dimmed": true, 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 540 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/TableOfContents/TableOfContents.module.css: -------------------------------------------------------------------------------- 1 | .link { 2 | display: block; 3 | text-decoration: none; 4 | color: var(--mantine-color-text); 5 | line-height: 1.2; 6 | font-size: var(--mantine-font-size-sm); 7 | padding: var(--mantine-spacing-xs); 8 | border-top-right-radius: var(--mantine-radius-sm); 9 | border-bottom-right-radius: var(--mantine-radius-sm); 10 | border-left: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 11 | 12 | @mixin hover { 13 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); 14 | } 15 | } 16 | 17 | .linkActive { 18 | font-weight: 500; 19 | border-left-color: light-dark(var(--mantine-color-blue-6), var(--mantine-color-blue-4)); 20 | color: light-dark(var(--mantine-color-blue-6), var(--mantine-color-blue-4)); 21 | 22 | &, 23 | &:hover { 24 | background-color: var(--mantine-color-blue-light) !important; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/TableOfContents/TableOfContents.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { TableOfContents } from './TableOfContents'; 4 | 5 | export default { title: 'TableOfContents' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={TableOfContents} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/TableOfContents/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Table of contents", 3 | "category": "toc", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 280 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/TableOfContentsFloating/TableOfContentsFloating.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { TableOfContentsFloating } from './TableOfContentsFloating'; 4 | 5 | export default { title: 'TableOfContentsFloating' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={TableOfContentsFloating} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/TableOfContentsFloating/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Table of contents indicator", 3 | "category": "toc", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 280 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/TableReviews/TableReviews.module.css: -------------------------------------------------------------------------------- 1 | .progressSection { 2 | &:not(:first-of-type) { 3 | border-left: 3px solid light-dark(var(--mantine-color-white), var(--mantine-color-dark-7)); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/TableReviews/TableReviews.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { TableReviews } from './TableReviews'; 4 | 5 | export default { title: 'TableReviews' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={TableReviews} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/TableReviews/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Table with progress", 3 | "category": "tables", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 920 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/TableScrollArea/TableScrollArea.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | position: sticky; 3 | top: 0; 4 | background-color: var(--mantine-color-body); 5 | transition: box-shadow 150ms ease; 6 | 7 | &::after { 8 | content: ''; 9 | position: absolute; 10 | left: 0; 11 | right: 0; 12 | bottom: 0; 13 | border-bottom: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-3)); 14 | } 15 | } 16 | 17 | .scrolled { 18 | box-shadow: var(--mantine-shadow-sm); 19 | } 20 | -------------------------------------------------------------------------------- /lib/TableScrollArea/TableScrollArea.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { TableScrollArea } from './TableScrollArea'; 4 | 5 | export default { title: 'TableScrollArea' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={TableScrollArea} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/TableScrollArea/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Table with sticky header", 3 | "category": "tables", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 920 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/TableSelection/TableSelection.module.css: -------------------------------------------------------------------------------- 1 | .rowSelected { 2 | background-color: var(--mantine-color-blue-light); 3 | } 4 | -------------------------------------------------------------------------------- /lib/TableSelection/TableSelection.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { TableSelection } from './TableSelection'; 4 | 5 | export default { title: 'TableSelection' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={TableSelection} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/TableSelection/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Table with selection", 3 | "category": "tables", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 800 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/TableSort/TableSort.module.css: -------------------------------------------------------------------------------- 1 | .th { 2 | padding: 0; 3 | } 4 | 5 | .control { 6 | width: 100%; 7 | padding: var(--mantine-spacing-xs) var(--mantine-spacing-md); 8 | 9 | @mixin hover { 10 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); 11 | } 12 | } 13 | 14 | .icon { 15 | width: 21px; 16 | height: 21px; 17 | border-radius: 21px; 18 | } 19 | -------------------------------------------------------------------------------- /lib/TableSort/TableSort.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { TableSort } from './TableSort'; 4 | 5 | export default { title: 'TableSort' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={TableSort} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/TableSort/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Table with search and sort", 3 | "category": "tables", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 920 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/TaskCard/TaskCard.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { TaskCard } from './TaskCard'; 4 | 5 | export default { title: 'TaskCard' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={TaskCard} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/TaskCard/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Tasks card", 3 | "category": "app-cards", 4 | "dimmed": true, 5 | "changelog": "september-2022", 6 | "canvas": { 7 | "center": true, 8 | "maxWidth": 360 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/UserButton/UserButton.module.css: -------------------------------------------------------------------------------- 1 | .user { 2 | display: block; 3 | width: 100%; 4 | padding: var(--mantine-spacing-md); 5 | color: light-dark(var(--mantine-color-black), var(--mantine-color-dark-0)); 6 | 7 | @mixin hover { 8 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-8)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/UserButton/UserButton.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { UserButton } from './UserButton'; 4 | 5 | export default { title: 'UserButton' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={UserButton} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/UserButton/UserButton.tsx: -------------------------------------------------------------------------------- 1 | import { IconChevronRight } from '@tabler/icons-react'; 2 | import { Avatar, Group, Text, UnstyledButton } from '@mantine/core'; 3 | import classes from './UserButton.module.css'; 4 | 5 | export function UserButton() { 6 | return ( 7 | <UnstyledButton className={classes.user}> 8 | <Group> 9 | <Avatar 10 | src="https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/avatars/avatar-8.png" 11 | radius="xl" 12 | /> 13 | 14 | <div style={{ flex: 1 }}> 15 | <Text size="sm" fw={500}> 16 | Harriette Spoonlicker 17 | </Text> 18 | 19 | <Text c="dimmed" size="xs"> 20 | hspoonlicker@outlook.com 21 | </Text> 22 | </div> 23 | 24 | <IconChevronRight size={14} stroke={1.5} /> 25 | </Group> 26 | </UnstyledButton> 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /lib/UserButton/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "User button", 3 | "category": "users", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 320 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/UserCardImage/UserCardImage.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: var(--mantine-color-body); 3 | } 4 | 5 | .avatar { 6 | border: 2px solid var(--mantine-color-body); 7 | } 8 | -------------------------------------------------------------------------------- /lib/UserCardImage/UserCardImage.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { UserCardImage } from './UserCardImage'; 4 | 5 | export default { title: 'UserCardImage' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={UserCardImage} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/UserCardImage/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "User card with image", 3 | "category": "users", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 300 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/UserInfoAction/UserInfoAction.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { UserInfoAction } from './UserInfoAction'; 4 | 5 | export default { title: 'UserInfoAction' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={UserInfoAction} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/UserInfoAction/UserInfoAction.tsx: -------------------------------------------------------------------------------- 1 | import { Avatar, Button, Paper, Text } from '@mantine/core'; 2 | 3 | export function UserInfoAction() { 4 | return ( 5 | <Paper radius="md" withBorder p="lg" bg="var(--mantine-color-body)"> 6 | <Avatar 7 | src="https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/avatars/avatar-8.png" 8 | size={120} 9 | radius={120} 10 | mx="auto" 11 | /> 12 | <Text ta="center" fz="lg" fw={500} mt="md"> 13 | Jane Fingerlicker 14 | </Text> 15 | <Text ta="center" c="dimmed" fz="sm"> 16 | jfingerlicker@me.io • Art director 17 | </Text> 18 | 19 | <Button variant="default" fullWidth mt="md"> 20 | Send message 21 | </Button> 22 | </Paper> 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /lib/UserInfoAction/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "User card with action", 3 | "category": "users", 4 | "dimmed": true, 5 | "canvas": { 6 | "center": true, 7 | "maxWidth": 320 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/UserInfoIcons/UserInfoIcons.module.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3)); 3 | } 4 | 5 | .name { 6 | font-family: Outfit, var(--mantine-font-family); 7 | } 8 | -------------------------------------------------------------------------------- /lib/UserInfoIcons/UserInfoIcons.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { UserInfoIcons } from './UserInfoIcons'; 4 | 5 | export default { title: 'UserInfoIcons' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={UserInfoIcons} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/UserInfoIcons/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "User info with icons", 3 | "category": "users", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 320 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/UserMenu/UserMenu.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { UserMenu } from './UserMenu'; 4 | 5 | export default { title: 'UserMenu' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={UserMenu} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/UserMenu/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "User menu", 3 | "category": "users", 4 | "canvas": { 5 | "center": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/UsersRolesTable/UsersRolesTable.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { UsersRolesTable } from './UsersRolesTable'; 4 | 5 | export default { title: 'UsersRolesTable' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={UsersRolesTable} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/UsersRolesTable/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Table with roles select", 3 | "category": "users", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 800 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/UsersStack/UsersStack.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { UsersStack } from './UsersStack'; 4 | 5 | export default { title: 'UsersStack' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={UsersStack} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/UsersStack/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Users stack", 3 | "category": "users", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 800 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/UsersTable/UsersTable.story.tsx: -------------------------------------------------------------------------------- 1 | import { StoryWrapper } from '../../components/StoryWrapper/StoryWrapper'; 2 | import attributes from './attributes.json'; 3 | import { UsersTable } from './UsersTable'; 4 | 5 | export default { title: 'UsersTable' }; 6 | 7 | export function Usage() { 8 | return <StoryWrapper attributes={attributes} component={UsersTable} />; 9 | } 10 | -------------------------------------------------------------------------------- /lib/UsersTable/attributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Table with users", 3 | "category": "users", 4 | "canvas": { 5 | "center": true, 6 | "maxWidth": 800 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// <reference types="next" /> 2 | /// <reference types="next/image-types/global" /> 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/pages/api-reference/config/typescript for more information. 6 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const config = { 3 | reactStrictMode: false, 4 | trailingSlash: true, 5 | output: 'export', 6 | eslint: { 7 | ignoreDuringBuilds: true, 8 | }, 9 | }; 10 | 11 | export default config; 12 | -------------------------------------------------------------------------------- /pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Head, Html, Main, NextScript } from 'next/document'; 2 | import { ColorSchemeScript } from '@mantine/core'; 3 | 4 | export default function Document() { 5 | return ( 6 | <Html lang="en"> 7 | <Head> 8 | <link rel="preconnect" href="https://fonts.googleapis.com" /> 9 | <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" /> 10 | <link 11 | href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap" 12 | rel="stylesheet" 13 | /> 14 | <ColorSchemeScript defaultColorScheme="auto" localStorageKey="mantine-ui-color-scheme" /> 15 | </Head> 16 | <body> 17 | <Main /> 18 | <NextScript /> 19 | </body> 20 | </Html> 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /pages/category/[category].tsx: -------------------------------------------------------------------------------- 1 | import { GetStaticPaths, GetStaticProps } from 'next'; 2 | import { CategoryPage } from '../../components/CategoryPage/CategoryPage'; 3 | import { CATEGORIES_SLUGS, Category, getCategoryData } from '../../data'; 4 | import { getAllComponents, getComponentsByCategory } from '../../data/components'; 5 | 6 | export default CategoryPage; 7 | 8 | export const getStaticPaths: GetStaticPaths = async () => ({ 9 | paths: CATEGORIES_SLUGS.map((slug) => ({ params: { category: slug } })), 10 | fallback: false, 11 | }); 12 | 13 | export const getStaticProps: GetStaticProps< 14 | { category: Category | undefined }, 15 | { category: string } 16 | > = (context) => ({ 17 | props: { 18 | category: getCategoryData(context!.params!.category), 19 | components: getComponentsByCategory()[context!.params!.category], 20 | allComponents: getAllComponents(), 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /pages/changelog/[changelog].tsx: -------------------------------------------------------------------------------- 1 | import { GetStaticPaths, GetStaticProps } from 'next'; 2 | import { ChangelogPage } from '../../components/ChangelogPage/ChangelogPage'; 3 | import { UiComponent } from '../../data'; 4 | import { 5 | getAllChangelogs, 6 | getAllComponents, 7 | getComponentsByChangelog, 8 | } from '../../data/components'; 9 | 10 | export default ChangelogPage; 11 | 12 | export const getStaticPaths: GetStaticPaths = async () => ({ 13 | paths: getAllChangelogs().map((changelog) => ({ params: { changelog } })), 14 | fallback: false, 15 | }); 16 | 17 | export const getStaticProps: GetStaticProps< 18 | { components: UiComponent[] }, 19 | { changelog: string } 20 | > = (context) => { 21 | const components = getComponentsByChangelog(context!.params!.changelog); 22 | const allComponents = getAllComponents(); 23 | return { props: { components, allComponents } }; 24 | }; 25 | -------------------------------------------------------------------------------- /pages/component/[component].tsx: -------------------------------------------------------------------------------- 1 | import { GetStaticPaths, GetStaticProps } from 'next'; 2 | import { ComponentPage } from '../../components/ComponentPage/ComponentPage'; 3 | import { UiComponent } from '../../data'; 4 | import { getAllComponents } from '../../data/components'; 5 | 6 | export default ComponentPage; 7 | 8 | export const getStaticPaths: GetStaticPaths = async () => ({ 9 | paths: getAllComponents().map((component) => ({ params: { component: component.slug } })), 10 | fallback: false, 11 | }); 12 | 13 | export const getStaticProps: GetStaticProps< 14 | { data: UiComponent | undefined }, 15 | { component: string } 16 | > = (context) => { 17 | const allComponents = getAllComponents(); 18 | return { 19 | props: { 20 | data: allComponents.find((component) => component.slug === context!.params!.component), 21 | allComponents, 22 | }, 23 | }; 24 | }; 25 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { GetStaticProps } from 'next'; 2 | import { HomePage } from '../components/HomePage/HomePage'; 3 | import { countComponentsByCategory, getAllComponents } from '../data/components'; 4 | 5 | export default HomePage; 6 | 7 | export const getStaticProps: GetStaticProps = () => ({ 8 | props: { 9 | componentsCountByCategory: countComponentsByCategory(), 10 | allComponents: getAllComponents(), 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | 'postcss-preset-mantine': { 4 | autoRem: true, 5 | }, 6 | 'postcss-simple-vars': { 7 | variables: { 8 | 'mantine-breakpoint-xs': '36em', 9 | 'mantine-breakpoint-sm': '48em', 10 | 'mantine-breakpoint-md': '62em', 11 | 'mantine-breakpoint-lg': '75em', 12 | 'mantine-breakpoint-xl': '88em', 13 | }, 14 | }, 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 500"><path fill="#22B8CF" d="M500 250C500 111.929 388.071 0 250 0S0 111.929 0 250s111.929 250 250 250 250-111.929 250-250z"/><path fill="#fff" d="M202.055 135.706c-6.26 8.373-4.494 20.208 3.944 26.42 29.122 21.45 45.824 54.253 45.824 90.005 0 35.752-16.702 68.559-45.824 90.005-8.436 6.215-10.206 18.043-3.944 26.42 6.26 8.378 18.173 10.13 26.611 3.916a153.816 153.816 0 0024.509-22.54h53.93c10.506 0 19.023-8.455 19.023-18.885 0-10.43-8.517-18.886-19.023-18.886h-29.79c8.196-18.594 12.553-38.923 12.553-60.03s-4.357-41.436-12.552-60.03h29.79c10.505 0 19.022-8.455 19.022-18.885 0-10.43-8.517-18.886-19.023-18.886h-53.93a153.863 153.863 0 00-24.509-22.54c-8.438-6.215-20.351-4.46-26.61 3.916h-.001z"/><path fill="#fff" fill-rule="evenodd" d="M171.992 246.492c0-15.572 12.624-28.195 28.196-28.195 15.572 0 28.195 12.623 28.195 28.195 0 15.572-12.623 28.196-28.195 28.196-15.572 0-28.196-12.624-28.196-28.196z" clip-rule="evenodd"/></svg> 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "paths": { 18 | "@/*": ["./*"] 19 | } 20 | }, 21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 22 | "exclude": ["node_modules"] 23 | } 24 | --------------------------------------------------------------------------------