├── .env
├── src
├── styles
│ ├── mantine-styles.css
│ ├── index.scss
│ └── fonts.css
├── vite-env.d.ts
├── components
│ ├── mantine
│ │ └── demo
│ │ │ ├── DemoRoot
│ │ │ ├── index.ts
│ │ │ ├── DemoRoot.module.css
│ │ │ └── DemoRoot.tsx
│ │ │ ├── DemoColumns
│ │ │ ├── index.ts
│ │ │ ├── DemoColumns.module.css
│ │ │ └── DemoColumns.tsx
│ │ │ ├── DemoArea
│ │ │ ├── index.ts
│ │ │ ├── DemoArea.tsx
│ │ │ └── DemoArea.module.css
│ │ │ ├── DemoCode
│ │ │ ├── index.ts
│ │ │ ├── DemoCode.module.scss
│ │ │ └── DemoCode.tsx
│ │ │ ├── ConfiguratorDemo
│ │ │ ├── ConfiguratorDemo.module.css
│ │ │ ├── controls
│ │ │ │ ├── get-control-label.ts
│ │ │ │ ├── types.ts
│ │ │ │ ├── transform-select-data.ts
│ │ │ │ ├── ConfiguratorColor.control.module.css
│ │ │ │ ├── ConfiguratorBoolean.control.tsx
│ │ │ │ ├── ConfiguratorString.control.tsx
│ │ │ │ ├── ConfiguratorNumber.control.tsx
│ │ │ │ ├── ConfiguratorSelect.control.tsx
│ │ │ │ ├── index.ts
│ │ │ │ ├── ConfiguratorSegmented.control.tsx
│ │ │ │ ├── ConfiguratorSize.control.tsx
│ │ │ │ └── ColorWheelIcon.tsx
│ │ │ ├── clear-props.ts
│ │ │ ├── get-code-array.ts
│ │ │ └── inject-props.tsx
│ │ │ ├── index.ts
│ │ │ ├── StylesApiDemo
│ │ │ └── StylesApiDemo.module.css
│ │ │ ├── Demo
│ │ │ └── Demo.tsx
│ │ │ └── CodeDemo
│ │ │ └── CodeDemo.tsx
│ ├── ui
│ │ ├── color-scheme-switch
│ │ │ ├── index.ts
│ │ │ ├── color-scheme-switch.module.css
│ │ │ └── color-scheme-switch.tsx
│ │ ├── navbar
│ │ │ ├── navbar.tsx
│ │ │ ├── navbar.module.scss
│ │ │ └── navbar-links-group.tsx
│ │ ├── chart-tooltip.tsx
│ │ └── header
│ │ │ └── header.module.scss
│ ├── custom
│ │ ├── components-demo
│ │ │ ├── components-demo.module.css
│ │ │ ├── charts
│ │ │ │ ├── data
│ │ │ │ │ ├── _pie-data.ts
│ │ │ │ │ ├── _donut-data.ts
│ │ │ │ │ ├── _bubble-data.ts
│ │ │ │ │ └── _radar-data.ts
│ │ │ │ ├── bubble-chart-demo.tsx
│ │ │ │ ├── scatter-chart-demo.tsx
│ │ │ │ ├── radar-chart-demo.tsx
│ │ │ │ ├── donot-chart-demo.tsx
│ │ │ │ ├── sparkline-demo.tsx
│ │ │ │ ├── pie-chart-demo.tsx
│ │ │ │ └── bar-chart-demo.tsx
│ │ │ ├── overlays
│ │ │ │ ├── tooltip-demo.tsx
│ │ │ │ ├── popover-demo.tsx
│ │ │ │ ├── modal-demo.tsx
│ │ │ │ ├── drawer-demo.tsx
│ │ │ │ ├── hover-card-demo.tsx
│ │ │ │ ├── loading-overlay-demo.tsx
│ │ │ │ ├── overlay-demo.tsx
│ │ │ │ └── dialog-demo.tsx
│ │ │ ├── data-display
│ │ │ │ ├── image-demo.tsx
│ │ │ │ ├── avatar-demo.tsx
│ │ │ │ ├── color-swatch-demo.tsx
│ │ │ │ ├── badge-demo.tsx
│ │ │ │ ├── theme-icon-demo.tsx
│ │ │ │ ├── background-image-demo.tsx
│ │ │ │ ├── spoiler-demo.tsx
│ │ │ │ ├── card-demo.tsx
│ │ │ │ └── indicator-demo.tsx
│ │ │ ├── inputs
│ │ │ │ ├── native-select-demo.tsx
│ │ │ │ ├── file-input.tsx
│ │ │ │ ├── textarea-demo.tsx
│ │ │ │ ├── color-input-demo.tsx
│ │ │ │ ├── text-input-demo.tsx
│ │ │ │ ├── rating-demo.tsx
│ │ │ │ ├── pin-input-demo.tsx
│ │ │ │ ├── chip-demo.tsx
│ │ │ │ ├── fieldset-demo.tsx
│ │ │ │ ├── switch-demo.tsx
│ │ │ │ ├── slider-demo.tsx
│ │ │ │ ├── segmented-control-demo.tsx
│ │ │ │ ├── switch-group-demo.tsx
│ │ │ │ ├── radio-group-demo.tsx
│ │ │ │ ├── radio-demo.tsx
│ │ │ │ ├── checkbox-group-demo.tsx
│ │ │ │ └── checkbox-demo.tsx
│ │ │ ├── miscellaneous
│ │ │ │ ├── date-picker-input-demo.tsx
│ │ │ │ └── paper-demo.tsx
│ │ │ ├── feedback
│ │ │ │ ├── loader-demo.tsx
│ │ │ │ ├── progress-demo.tsx
│ │ │ │ ├── skeleton-demo.tsx
│ │ │ │ ├── notification-demo.tsx
│ │ │ │ ├── alert-demo.tsx
│ │ │ │ ├── semi-circle-progress-demo.tsx
│ │ │ │ └── ring-progress-demo.tsx
│ │ │ ├── typography
│ │ │ │ ├── mark-demo.tsx
│ │ │ │ ├── code-demo.tsx
│ │ │ │ ├── highlight-demo.tsx
│ │ │ │ ├── title-demo.tsx
│ │ │ │ ├── blockquote-demo.tsx
│ │ │ │ ├── list-demo.tsx
│ │ │ │ ├── text-demo.tsx
│ │ │ │ └── table-demo.tsx
│ │ │ ├── buttons
│ │ │ │ ├── close-button-demo.tsx
│ │ │ │ ├── button-demo.tsx
│ │ │ │ └── action-icon-demo.tsx
│ │ │ ├── combobox
│ │ │ │ ├── select-demo.tsx
│ │ │ │ ├── multi-select-demo.tsx
│ │ │ │ ├── autocomplete-demo.tsx
│ │ │ │ ├── tags-input-demo.tsx
│ │ │ │ └── pills-input-demo.tsx
│ │ │ ├── navigation
│ │ │ │ ├── pagination-demo.tsx
│ │ │ │ ├── anchor-demo.tsx
│ │ │ │ └── stepper-demo.tsx
│ │ │ └── components-demo.tsx
│ │ ├── testimonial
│ │ │ ├── testimonial-grid.tsx
│ │ │ └── testimonial-item.tsx
│ │ ├── theme-example-cards
│ │ │ ├── calendar.tsx
│ │ │ ├── create-account.tsx
│ │ │ ├── metric.tsx
│ │ │ ├── mantine-cards.tsx
│ │ │ ├── cookie-settings.tsx
│ │ │ └── report-issue.tsx
│ │ ├── change-theme-section
│ │ │ └── change-theme-section.tsx
│ │ └── blocks
│ │ │ └── coming-soon
│ │ │ └── coming-soon.module.css
│ ├── MicrosoftClarity.tsx
│ └── GoogleAnalytics.tsx
├── themes
│ ├── generated
│ │ └── generatedMantineCssStyles.ts
│ └── mantine
│ │ ├── mantine-css-variable-resolver.ts
│ │ └── mantine-theme.ts
├── assets
│ └── fonts
│ │ ├── Geist-Black.woff2
│ │ ├── Geist-Bold.woff2
│ │ ├── Geist-Light.woff2
│ │ ├── Geist-Thin.woff2
│ │ ├── Geist[wght].woff2
│ │ ├── Geist-Medium.woff2
│ │ ├── Geist-Regular.woff2
│ │ ├── Geist-SemiBold.woff2
│ │ ├── Geist-ExtraBold.woff2
│ │ └── Geist-ExtraLight.woff2
├── feature
│ └── blocks
│ │ ├── lib
│ │ ├── hero1
│ │ │ ├── attributes.json
│ │ │ └── hero1.module.css
│ │ ├── feature1
│ │ │ ├── attributes.json
│ │ │ └── feature1.module.css
│ │ ├── pricing1
│ │ │ ├── attributes.json
│ │ │ └── pricing1.module.css
│ │ ├── coming-soon
│ │ │ ├── attributes.json
│ │ │ ├── coming-soon.module.css
│ │ │ └── coming-soon.tsx
│ │ ├── meet-our-team-1
│ │ │ ├── attributes.json
│ │ │ └── meet-our-team-1.module.css
│ │ └── index.ts
│ │ ├── components
│ │ ├── shell
│ │ │ ├── shell.module.css
│ │ │ └── shell.tsx
│ │ ├── block-components
│ │ │ └── block-components.tsx
│ │ ├── component-preview
│ │ │ └── component-preview.tsx
│ │ └── component-canvas
│ │ │ ├── color-control.tsx
│ │ │ ├── component-canvas.module.css
│ │ │ └── component-canvas.tsx
│ │ └── data
│ │ └── types.ts
├── app
│ ├── loading.tsx
│ ├── playground
│ │ └── page.tsx
│ ├── blocks
│ │ └── page.tsx
│ ├── page.tsx
│ ├── how-to-use
│ │ └── page.tsx
│ ├── sitemap.ts
│ ├── feedback
│ │ └── page.tsx
│ └── about
│ │ └── page.tsx
├── utils
│ ├── cssTemplate.ts
│ ├── variants-data.ts
│ ├── themeTemplate.ts
│ └── input-controls.ts
└── _mantine.scss
├── public
├── _redirects
├── robots.txt
└── favicon.svg
├── tsconfig.node.tsbuildinfo
├── .prettierrc
├── next-env.d.ts
├── tailwind.config.js
├── .gitignore
├── postcss.config.js
├── next.config.js
├── tsconfig.app.json
├── eslint.config.js
├── js
└── scripts
│ ├── generateStyles.cjs
│ └── compileTS.cjs
├── LICENSE
├── favicon.svg
├── tsconfig.json
├── _mantine.scss
└── package.json
/.env:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_BASE_PATH=""
--------------------------------------------------------------------------------
/src/styles/mantine-styles.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/_redirects:
--------------------------------------------------------------------------------
1 | /* /index.html 200
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/tsconfig.node.tsbuildinfo:
--------------------------------------------------------------------------------
1 | {"root":["./vite.config.ts"],"version":"5.6.3"}
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoRoot/index.ts:
--------------------------------------------------------------------------------
1 | export { DemoRoot } from './DemoRoot';
2 |
--------------------------------------------------------------------------------
/src/components/ui/color-scheme-switch/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./color-scheme-switch";
2 |
--------------------------------------------------------------------------------
/src/themes/generated/generatedMantineCssStyles.ts:
--------------------------------------------------------------------------------
1 | export const generatedMantineCssStyles = ``;
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoColumns/index.ts:
--------------------------------------------------------------------------------
1 | export { DemoColumns } from './DemoColumns';
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "singleQuote": false,
4 | "trailingComma": "es5",
5 | "printWidth": 120
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoArea/index.ts:
--------------------------------------------------------------------------------
1 | export { DemoArea } from './DemoArea';
2 | export type { DemoAreaProps } from './DemoArea';
3 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoCode/index.ts:
--------------------------------------------------------------------------------
1 | export { DemoCode } from './DemoCode';
2 | export type { DemoCodeProps } from './DemoCode';
3 |
--------------------------------------------------------------------------------
/src/assets/fonts/Geist-Black.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RubixCube-Innovations/mantine-theme-builder/HEAD/src/assets/fonts/Geist-Black.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/Geist-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RubixCube-Innovations/mantine-theme-builder/HEAD/src/assets/fonts/Geist-Bold.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/Geist-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RubixCube-Innovations/mantine-theme-builder/HEAD/src/assets/fonts/Geist-Light.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/Geist-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RubixCube-Innovations/mantine-theme-builder/HEAD/src/assets/fonts/Geist-Thin.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/Geist[wght].woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RubixCube-Innovations/mantine-theme-builder/HEAD/src/assets/fonts/Geist[wght].woff2
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/ConfiguratorDemo.module.css:
--------------------------------------------------------------------------------
1 | .controls {
2 | padding: calc(var(--mantine-spacing-md) - 4px);
3 | }
4 |
--------------------------------------------------------------------------------
/src/assets/fonts/Geist-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RubixCube-Innovations/mantine-theme-builder/HEAD/src/assets/fonts/Geist-Medium.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/Geist-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RubixCube-Innovations/mantine-theme-builder/HEAD/src/assets/fonts/Geist-Regular.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/Geist-SemiBold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RubixCube-Innovations/mantine-theme-builder/HEAD/src/assets/fonts/Geist-SemiBold.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/Geist-ExtraBold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RubixCube-Innovations/mantine-theme-builder/HEAD/src/assets/fonts/Geist-ExtraBold.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/Geist-ExtraLight.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RubixCube-Innovations/mantine-theme-builder/HEAD/src/assets/fonts/Geist-ExtraLight.woff2
--------------------------------------------------------------------------------
/src/components/custom/components-demo/components-demo.module.css:
--------------------------------------------------------------------------------
1 | .navbarWrapper{
2 | position: sticky;
3 | top: 80px;
4 | z-index: 1;
5 | }
6 |
7 | .content {
8 | flex: 1;
9 | }
--------------------------------------------------------------------------------
/src/feature/blocks/lib/hero1/attributes.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "hero1",
3 | "category": "hero",
4 | "canvas": {
5 | "center": true,
6 | "maxWidth": 1200
7 | },
8 | "order": 1
9 | }
10 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/feature1/attributes.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "feature1",
3 | "category": "feature",
4 | "canvas": {
5 | "center": true,
6 | "maxWidth": 1200
7 | },
8 | "order": 2
9 | }
10 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/pricing1/attributes.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "pricing1",
3 | "category": "pricing",
4 | "canvas": {
5 | "center": true,
6 | "maxWidth": 1200
7 | },
8 | "order": 3
9 | }
10 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoRoot/DemoRoot.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | border: 1px solid var(--demo-border);
3 | border-radius: var(--mantine-radius-md);
4 | --demo-border: var(--mantine-color-default-border);
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/index.ts:
--------------------------------------------------------------------------------
1 | export { Demo } from './Demo/Demo';
2 | export type { MantineDemo } from './Demo/Demo';
3 | export type { ConfiguratorControlOptions } from './ConfiguratorDemo/ConfiguratorDemo';
4 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/coming-soon/attributes.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "coming-soon",
3 | "category": "coming-soon",
4 | "canvas": {
5 | "center": true,
6 | "maxWidth": 1200
7 | },
8 | "order": 5
9 | }
10 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/meet-our-team-1/attributes.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "meet-our-team-1",
3 | "category": "team",
4 | "canvas": {
5 | "center": true,
6 | "maxWidth": 1200
7 | },
8 | "order": 4
9 | }
10 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ["./src/**/*.{js,ts,jsx,tsx}"],
4 | theme: {
5 | extend: {},
6 | },
7 | corePlugins: { preflight: false, },
8 | plugins: [],
9 | };
10 |
--------------------------------------------------------------------------------
/src/app/loading.tsx:
--------------------------------------------------------------------------------
1 | import { Center, Loader } from "@mantine/core";
2 |
3 | export default function Loading() {
4 | return (
5 |
6 |
7 |
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # Allow all crawlers
2 | User-agent: *
3 | Allow: /
4 |
5 | # Sitemap location
6 | Sitemap: https://mantinehub.com/sitemap.xml
7 |
8 | # Disallow admin and private routes
9 | Disallow: /api/
10 | Disallow: /_next/
11 | Disallow: /static/
--------------------------------------------------------------------------------
/src/feature/blocks/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: rem(120px);
10 | }
11 |
--------------------------------------------------------------------------------
/src/utils/cssTemplate.ts:
--------------------------------------------------------------------------------
1 | export const generateCSSTemplate = () => {
2 | return `
3 |
4 | .globalMantineInput {
5 | &:focus-within {
6 | outline: rem(1px) solid var(--mantine-primary-color-filled) ;
7 | }
8 | }
9 |
10 | `;
11 | };
12 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/get-control-label.ts:
--------------------------------------------------------------------------------
1 | import { upperFirst } from '@mantine/hooks';
2 |
3 | export function getControlLabel(label: string) {
4 | return upperFirst(label.replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase());
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoRoot/DemoRoot.tsx:
--------------------------------------------------------------------------------
1 | import cx from "clsx";
2 | import classes from "./DemoRoot.module.css";
3 |
4 | export function DemoRoot({ className, ...others }: React.ComponentPropsWithoutRef<"div">) {
5 | return ;
6 | }
7 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/index.ts:
--------------------------------------------------------------------------------
1 | export { Hero1 } from "./hero1/hero1";
2 | export { Feature1 } from "./feature1/feature1";
3 | export { Pricing1 } from "./pricing1/pricing1";
4 | export { ComingSoon } from "./coming-soon/coming-soon";
5 | export { MeetOurTeam1 } from "./meet-our-team-1/meet-our-team-1";
6 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoCode/DemoCode.module.scss:
--------------------------------------------------------------------------------
1 | .code {
2 | border-bottom-right-radius: var(--mantine-radius-md);
3 | border-bottom-left-radius: var(--mantine-radius-md);
4 | overflow: hidden;
5 | border-top: 1px solid var(--demo-border);
6 |
7 | @mixin mobile {
8 | max-width: calc(100vw - 32px);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/coming-soon/coming-soon.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | padding: 4rem 1rem;
3 | }
4 |
5 | .title {
6 | background-image: linear-gradient(to right, #eea2a2 0%, #bbc1bf 19%, #57c6e1 42%, #b49fda 79%, #7ac5d8 100%);
7 | background-clip: text;
8 | -webkit-background-clip: text;
9 | -webkit-text-fill-color: transparent;
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/types.ts:
--------------------------------------------------------------------------------
1 | export type ConfiguratorControl> = {
2 | type: Type;
3 | prop: string;
4 | libraryValue?: any;
5 | initialValue?: any;
6 | transformLabel?: boolean;
7 | } & Params;
8 |
9 | export type ShikiLanguage = "tsx" | "scss" | "html" | "bash" | "json";
10 |
--------------------------------------------------------------------------------
/src/components/ui/color-scheme-switch/color-scheme-switch.module.css:
--------------------------------------------------------------------------------
1 | .icon {
2 | width: 18x;
3 | height: 18x;
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 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | .next
16 | next-env.d.ts
17 | dist
18 |
19 | # Editor directories and files
20 | .vscode/*
21 | !.vscode/extensions.json
22 | .idea
23 | .DS_Store
24 | *.suo
25 | *.ntvs*
26 | *.njsproj
27 | *.sln
28 | *.sw?
29 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/hero1/hero1.module.css:
--------------------------------------------------------------------------------
1 | .title {
2 | font-size: clamp(2.5rem, 5vw, 4rem);
3 | line-height: 1;
4 | background: linear-gradient(80deg, var(--mantine-primary-color-filled), var(--mantine-primary-color-8));
5 |
6 | -webkit-background-clip: text;
7 | -webkit-text-fill-color: transparent;
8 | }
9 |
10 | .themeIconBackground {
11 | background: rgba(var(--mantine-primary-color-filled), 0.07);
12 | }
13 |
--------------------------------------------------------------------------------
/src/themes/mantine/mantine-css-variable-resolver.ts:
--------------------------------------------------------------------------------
1 | import { CSSVariablesResolver } from "@mantine/core";
2 |
3 | export const mantineCssVariableResolver: CSSVariablesResolver = () => ({
4 | variables: {
5 | // variables that do not depend on color scheme
6 | },
7 | light: {
8 | // variables for light color scheme only
9 | },
10 | dark: {
11 | // variables for dark color scheme only
12 | },
13 | });
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | "postcss-preset-mantine": {},
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 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/StylesApiDemo/StylesApiDemo.module.css:
--------------------------------------------------------------------------------
1 | .selector {
2 | display: block;
3 | width: 100%;
4 | font-size: var(--mantine-font-size-sm);
5 | padding: 6px var(--mantine-spacing-sm);
6 | border-radius: var(--mantine-radius-sm);
7 | cursor: help;
8 |
9 | @mixin hover {
10 | @mixin light {
11 | background-color: var(--mantine-color-gray-0);
12 | }
13 |
14 | @mixin dark {
15 | background-color: var(--mantine-color-dark-6);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/app/playground/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import ComponentsDemo from "@/components/custom/components-demo/components-demo";
4 | import PageLayout from "@/components/layouts/page-layout";
5 |
6 | export default function Page() {
7 | return (
8 |
12 |
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/blocks/page.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 | import PageLayout from "@/components/layouts/page-layout";
3 | import BlockComponents from "@/feature/blocks/components/block-components/block-components";
4 |
5 | export default function Page() {
6 | return (
7 |
12 |
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/custom/testimonial/testimonial-grid.tsx:
--------------------------------------------------------------------------------
1 | import { SimpleGrid } from "@mantine/core";
2 | import { ITestimonialItem, TestimonialItem } from "./testimonial-item";
3 |
4 | export const TestimonialGrid = ({ testimonialItems }: { testimonialItems: Array }) => {
5 | return (
6 |
10 | {testimonialItems.map((testimonial, index) => (
11 |
12 | ))}
13 |
14 | );
15 | };
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | import path from "node:path";
3 |
4 | const nextConfig = {
5 | output: "export", // Outputs a Single-Page Application (SPA).
6 | distDir: "./dist", // Changes the build output directory to `./dist/`.
7 | basePath: process.env.NEXT_PUBLIC_BASE_PATH, // Sets the base path to `/some-base-path`.
8 | sassOptions: {
9 | implementation: "sass-embedded",
10 | additionalData: `@use "${path.join(process.cwd(), "_mantine").replace(/\\/g, "/")}" as mantine;`,
11 | },
12 | };
13 |
14 | export default nextConfig;
15 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/transform-select-data.ts:
--------------------------------------------------------------------------------
1 | import { upperFirst } from '@mantine/hooks';
2 |
3 | interface SelectDataItem {
4 | label: string;
5 | value: string;
6 | }
7 |
8 | export type SelectData = (string | SelectDataItem)[];
9 |
10 | export function transformSelectData(data: SelectData): SelectDataItem[] {
11 | return data.map((item) => {
12 | if (typeof item === 'string') {
13 | return { label: upperFirst(item), value: item };
14 | }
15 |
16 | return { value: item.value, label: upperFirst(item.label) };
17 | });
18 | }
19 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/data/_pie-data.ts:
--------------------------------------------------------------------------------
1 | export const data = [
2 | { name: 'USA', value: 400, color: 'indigo.6' },
3 | { name: 'India', value: 300, color: 'yellow.6' },
4 | { name: 'Japan', value: 300, color: 'teal.6' },
5 | { name: 'Other', value: 200, color: 'gray.6' },
6 | ];
7 |
8 | export const dataCode = `
9 | export const data = [
10 | { name: 'USA', value: 400, color: 'indigo.6' },
11 | { name: 'India', value: 300, color: 'yellow.6' },
12 | { name: 'Japan', value: 300, color: 'teal.6' },
13 | { name: 'Other', value: 200, color: 'gray.6' },
14 | ];
15 | `;
16 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/data/_donut-data.ts:
--------------------------------------------------------------------------------
1 | export const data = [
2 | { name: 'USA', value: 400, color: 'indigo.6' },
3 | { name: 'India', value: 300, color: 'yellow.6' },
4 | { name: 'Japan', value: 100, color: 'teal.6' },
5 | { name: 'Other', value: 200, color: 'gray.6' },
6 | ];
7 |
8 | export const dataCode = `
9 | export const data = [
10 | { name: 'USA', value: 400, color: 'indigo.6' },
11 | { name: 'India', value: 300, color: 'yellow.6' },
12 | { name: 'Japan', value: 100, color: 'teal.6' },
13 | { name: 'Other', value: 200, color: 'gray.6' },
14 | ];
15 | `;
16 |
--------------------------------------------------------------------------------
/src/components/MicrosoftClarity.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import Script from 'next/script';
4 |
5 | export default function MicrosoftClarity() {
6 | return (
7 |
16 | );
17 | }
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/clear-props.ts:
--------------------------------------------------------------------------------
1 | import type { ConfiguratorControlOptions } from './ConfiguratorDemo';
2 |
3 | type Values = Record;
4 |
5 | export function clearProps(controls: ConfiguratorControlOptions[], state: Values) {
6 | const normalizedControls = controls.reduce((acc, control) => {
7 | acc[control.prop] = control.libraryValue;
8 | return acc;
9 | }, {});
10 |
11 | return Object.keys(state).reduce((acc, key) => {
12 | if (state[key] !== normalizedControls[key]) {
13 | acc[key] = state[key];
14 | }
15 | return acc;
16 | }, {});
17 | }
18 |
--------------------------------------------------------------------------------
/src/feature/blocks/components/block-components/block-components.tsx:
--------------------------------------------------------------------------------
1 | import { Container } from "@mantine/core";
2 | import { ComponentCanvas } from "../component-canvas/component-canvas";
3 | import { components } from "../../data/components";
4 |
5 | const BlockComponents = () => {
6 | const canvases = components.map((component, index) => (
7 |
8 | ));
9 |
10 | return (
11 |
12 | {canvases}
13 |
14 | );
15 | };
16 |
17 | export default BlockComponents;
18 |
--------------------------------------------------------------------------------
/src/components/GoogleAnalytics.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import Script from 'next/script';
4 |
5 | export default function GoogleAnalytics() {
6 | return (
7 | <>
8 |
12 |
20 | >
21 | );
22 | }
--------------------------------------------------------------------------------
/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "isolatedModules": true,
13 | "moduleDetection": "force",
14 | "noEmit": true,
15 | "jsx": "react-jsx",
16 |
17 | /* Linting */
18 | "strict": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "noFallthroughCasesInSwitch": true
22 | },
23 | "include": ["src"],
24 | "exclude": ["js"]
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/overlays/tooltip-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Tooltip } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Tooltip, Button } from '@mantine/core';
6 |
7 | function Demo() {
8 | return (
9 |
10 |
11 |
12 | );
13 | }
14 | `;
15 |
16 | function Demo() {
17 | return (
18 |
19 |
20 |
21 | );
22 | }
23 |
24 | export const tooltipDemo: MantineDemo = {
25 | type: 'code',
26 | component: Demo,
27 | centered: true,
28 | code,
29 | };
30 |
--------------------------------------------------------------------------------
/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import MantineCards from "@/components/custom/theme-example-cards/mantine-cards";
4 | import PageLayout from "@/components/layouts/page-layout";
5 | import { Anchor } from "@mantine/core";
6 |
7 | export default function Page() {
8 | return (
9 |
13 | Save time on styling with our ready-to-use themes for{" "}
14 |
15 | Mantine
16 | {" "}
17 | components. Just copy, paste, and watch your app come to life.
18 | >
19 | }
20 | >
21 |
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/data-display/image-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Image } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Image } from '@mantine/core';
6 |
7 | function Demo() {
8 | return (
9 |
13 | );
14 | }
15 | `;
16 |
17 | function Demo() {
18 | return (
19 |
23 | );
24 | }
25 |
26 | export const imageDemo: MantineDemo = {
27 | type: 'code',
28 | component: Demo,
29 | code,
30 | };
31 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/native-select-demo.tsx:
--------------------------------------------------------------------------------
1 | import { NativeSelect } from "@mantine/core";
2 | import { MantineDemo } from "../../../mantine/demo";
3 | import { inputControls } from "../../../../utils/input-controls";
4 |
5 | const code = `
6 | import { NativeSelect } from '@mantine/core';
7 |
8 | function Demo() {
9 | return ;
10 | }
11 | `;
12 |
13 | function Wrapper(props: any) {
14 | return ;
15 | }
16 |
17 | export const nativeSelectDemo: MantineDemo = {
18 | type: "configurator",
19 | component: Wrapper,
20 | code,
21 | centered: true,
22 | maxWidth: 340,
23 | controls: inputControls,
24 | };
25 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/file-input.tsx:
--------------------------------------------------------------------------------
1 | import { FileInput } from "@mantine/core";
2 | import { MantineDemo } from "../../../mantine/demo";
3 | import { inputControls } from "../../../../utils/input-controls";
4 |
5 | const code = `
6 | import { FileInput } from '@mantine/core';
7 |
8 |
9 | function Demo() {
10 | return (
11 |
15 | );
16 | }
17 | `;
18 |
19 | function Wrapper(props: any) {
20 | return ;
21 | }
22 |
23 | export const fileInputDemo: MantineDemo = {
24 | type: "configurator",
25 | component: Wrapper,
26 | code,
27 | centered: true,
28 | maxWidth: 340,
29 | controls: inputControls,
30 | };
31 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/textarea-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Textarea } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { inputControls } from '../../../../utils/input-controls';
4 |
5 | const code = `
6 | import { Textarea } from '@mantine/core';
7 |
8 |
9 | function Demo() {
10 | return (
11 |
15 | );
16 | }
17 | `;
18 |
19 | function Wrapper(props: any) {
20 | return ;
21 | }
22 |
23 | export const textareaDemo: MantineDemo = {
24 | type: 'configurator',
25 | component: Wrapper,
26 | code,
27 | centered: true,
28 | maxWidth: 340,
29 | controls: inputControls,
30 | };
31 |
--------------------------------------------------------------------------------
/src/components/custom/theme-example-cards/calendar.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import { Card } from "@mantine/core";
3 | import { DatePicker } from "@mantine/dates";
4 |
5 | export function CardsCalendar() {
6 | const [value, setValue] = useState<[Date | null, Date | null]>([new Date(2023, 5, 5), new Date(2023, 5, 13)]);
7 |
8 | return (
9 |
10 | {
15 | if (dates[0] && dates[1]) {
16 | setValue(dates as [Date, Date]);
17 | }
18 | }}
19 | firstDayOfWeek={0}
20 | defaultDate={new Date(2023, 5)}
21 | withCellSpacing={false}
22 | />
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/custom/change-theme-section/change-theme-section.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Group } from "@mantine/core";
2 | import ChangeThemeButton from "./change-theme-button";
3 | import CopyThemeCodeButton from "./copy-theme-code-button";
4 |
5 | const ChangeThemeSection = ({ isBlockPage = false }: { isBlockPage?: boolean }) => {
6 | return (
7 |
8 |
9 | {isBlockPage ? (
10 |
13 | ) : (
14 |
15 | )}
16 |
17 | );
18 | };
19 |
20 | export default ChangeThemeSection;
21 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/ConfiguratorColor.control.module.css:
--------------------------------------------------------------------------------
1 | .swatch {
2 | cursor: pointer;
3 | display: flex;
4 | align-items: center;
5 | justify-content: center;
6 | color: var(--mantine-color-white);
7 | flex: 1 0 calc(15% - 4px);
8 | }
9 |
10 | .check {
11 | width: 12px;
12 | height: 12px;
13 | }
14 |
15 | .colorControl {
16 | cursor: pointer;
17 | display: flex;
18 | align-items: center;
19 | justify-content: center;
20 | flex: 1 0 calc(15% - 4px);
21 | height: 28px;
22 | border-radius: var(--mantine-radius-sm);
23 | border: 1px solid;
24 |
25 | @mixin where-light {
26 | border-color: var(--mantine-color-gray-5);
27 | }
28 |
29 | @mixin where-dark {
30 | border-color: var(--mantine-color-dark-3);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/color-input-demo.tsx:
--------------------------------------------------------------------------------
1 | import { ColorInput } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { inputControls } from '../../../../utils/input-controls';
4 |
5 | const code = `
6 | import { ColorInput } from '@mantine/core';
7 |
8 |
9 | function Demo() {
10 | return (
11 |
15 | );
16 | }
17 | `;
18 |
19 | function Wrapper(props: any) {
20 | return ;
21 | }
22 |
23 | export const colorInputDemo: MantineDemo = {
24 | type: 'configurator',
25 | component: Wrapper,
26 | code,
27 | centered: true,
28 | maxWidth: 340,
29 | controls: inputControls,
30 | };
31 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/text-input-demo.tsx:
--------------------------------------------------------------------------------
1 | import { TextInput } from '@mantine/core';
2 | import { inputControls } from '../../../../utils/input-controls';
3 | import { MantineDemo } from '../../../mantine/demo';
4 |
5 | const code = `
6 | import { TextInput } from '@mantine/core';
7 |
8 |
9 | function Demo() {
10 | return (
11 |
15 | );
16 | }
17 | `;
18 |
19 | function Wrapper(props: any) {
20 | return ;
21 | }
22 |
23 | export const textInputDemo: MantineDemo
24 | = {
25 | type: 'configurator',
26 | component: Wrapper,
27 | code,
28 | centered: true,
29 | maxWidth: 340,
30 | controls: inputControls,
31 | };
32 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/miscellaneous/date-picker-input-demo.tsx:
--------------------------------------------------------------------------------
1 | import { DateInput } from '@mantine/dates';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { inputControls } from '../../../../utils/input-controls';
4 |
5 | const code = `
6 | import { DateInput } from '@mantine/dates';
7 |
8 |
9 | function Demo() {
10 | return (
11 |
15 | );
16 | }
17 | `;
18 |
19 | function Wrapper(props: any) {
20 | return ;
21 | }
22 |
23 | export const dateInputDemo: MantineDemo = {
24 | type: 'configurator',
25 | component: Wrapper,
26 | code,
27 | centered: true,
28 | maxWidth: 340,
29 | controls: inputControls,
30 | };
31 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/feedback/loader-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Loader } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Loader } from '@mantine/core';
6 |
7 | function Demo() {
8 | return ;
9 | }
10 | `;
11 |
12 | export const loaderDemo: MantineDemo = {
13 | type: 'configurator',
14 | component: Loader,
15 | code,
16 | centered: true,
17 | controls: [
18 | { type: 'color', prop: 'color', initialValue: '', libraryValue: '' },
19 | { type: 'size', prop: 'size', initialValue: 'md', libraryValue: 'md' },
20 | {
21 | type: 'segmented',
22 | prop: 'type',
23 | data: ['oval', 'bars', 'dots'],
24 | initialValue: 'oval',
25 | libraryValue: 'oval',
26 | },
27 | ],
28 | };
29 |
--------------------------------------------------------------------------------
/src/utils/variants-data.ts:
--------------------------------------------------------------------------------
1 | import { ConfiguratorControlOptions } from "../components/mantine/demo";
2 |
3 | export const STATIC_VARIANTS = ['filled', 'light', 'outline', 'transparent', 'white', 'default'];
4 |
5 | export const INTERACTIVE_VARIANTS = [
6 | 'default',
7 | 'filled',
8 | 'light',
9 | 'outline',
10 | 'subtle',
11 | 'transparent',
12 | 'white',
13 | ];
14 |
15 | export const interactiveVariantsControl: ConfiguratorControlOptions = {
16 | type: 'select',
17 | prop: 'variant',
18 | data: INTERACTIVE_VARIANTS,
19 | initialValue: 'filled',
20 | libraryValue: 'filled',
21 | };
22 |
23 | export const staticVariantsControl: ConfiguratorControlOptions = {
24 | type: 'select',
25 | prop: 'variant',
26 | data: STATIC_VARIANTS,
27 | initialValue: '',
28 | libraryValue: '',
29 | };
30 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/coming-soon/coming-soon.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Container, Text, Group, Stack } from "@mantine/core";
2 | import styles from "./coming-soon.module.css";
3 |
4 | export const ComingSoon = () => {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 | Coming Soon..
12 |
13 |
14 | We're working hard to bring you more awesome blocks. Stay tuned for updates!
15 |
16 |
17 |
18 |
19 |
20 | );
21 | };
22 |
--------------------------------------------------------------------------------
/src/app/how-to-use/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { HowToUsePage } from "@/components/custom/how-to-use/how-to-use";
4 | import PageLayout from "@/components/layouts/page-layout";
5 | import { Box, Space, Stack } from "@mantine/core";
6 |
7 | export default function Page() {
8 | return (
9 |
14 |
15 |
16 |
21 |
22 |
23 |
24 |
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/typography/mark-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Mark, MarkProps, Text } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: MarkProps) {
5 | return (
6 |
7 | Highlight this chunk of the text
8 |
9 | );
10 | }
11 |
12 | const code = `
13 | import { Text, Mark } from '@mantine/core';
14 |
15 | function Demo() {
16 | return (
17 |
18 | Highlight this chunk of the text
19 |
20 | );
21 | }
22 | `;
23 |
24 | export const markDemo: MantineDemo = {
25 | type: 'configurator',
26 | component: Wrapper,
27 | code,
28 | centered: true,
29 | maxWidth: '100%',
30 | controls: [{ prop: 'color', type: 'color', initialValue: '', libraryValue: '' }],
31 | };
32 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/typography/code-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Code } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Code } from '@mantine/core';
6 |
7 | const codeForPreviousDemo = \`
8 | import { Code } from '@mantine/core';
9 |
10 | function Demo() {
11 | return React.createElement();
12 | }\`;
13 |
14 | function Demo() {
15 | return {codeForPreviousDemo};
16 | }
17 | `;
18 |
19 | const codeForPreviousDemo = `
20 | import { Code } from '@mantine/core';
21 |
22 | function Demo() {
23 | return React.createElement();
24 | }`;
25 |
26 | function Demo() {
27 | return {codeForPreviousDemo};
28 | }
29 |
30 | export const codeDemo: MantineDemo = {
31 | type: 'code',
32 | code,
33 | component: Demo,
34 | };
35 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/buttons/close-button-demo.tsx:
--------------------------------------------------------------------------------
1 | import { CloseButton } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { CloseButton } from '@mantine/core';
6 |
7 | function Demo() {
8 | return ;
9 | }
10 | `;
11 |
12 | function Wrapper(props: any) {
13 | return ;
14 | }
15 |
16 | export const closeButtonDemo: MantineDemo = {
17 | type: 'configurator',
18 | component: Wrapper,
19 | code,
20 | centered: true,
21 | controls: [
22 | { prop: 'size', type: 'size', initialValue: 'md', libraryValue: 'md' },
23 | {
24 | prop: 'variant',
25 | type: 'segmented',
26 | data: ['transparent', 'subtle'],
27 | libraryValue: 'subtle',
28 | initialValue: 'subtle',
29 | },
30 | ],
31 | };
32 |
--------------------------------------------------------------------------------
/src/feature/blocks/components/component-preview/component-preview.tsx:
--------------------------------------------------------------------------------
1 | import { Box, rem } from "@mantine/core";
2 | import { CanvasAttributes } from "../../data/types";
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 |
21 | {children}
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/data-display/avatar-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Avatar } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { staticVariantsControl } from '../../../../utils/variants-data';
4 |
5 | const code = `
6 | import { Avatar } from '@mantine/core';
7 |
8 | function Demo() {
9 | return ;
10 | }
11 | `;
12 |
13 | export const avatarDemo: MantineDemo = {
14 | type: "configurator",
15 | component: Avatar,
16 | centered: true,
17 | code,
18 | controls: [
19 | { ...(staticVariantsControl as any), initialValue: 'light', libraryValue: 'light' },
20 | { prop: "radius", type: "size", initialValue: "sm", libraryValue: "100%" },
21 | { prop: "size", type: "size", initialValue: "md", libraryValue: "md" },
22 | { prop: "color", type: "color", initialValue: "", libraryValue: "" },
23 | ],
24 | };
25 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoCode/DemoCode.tsx:
--------------------------------------------------------------------------------
1 | import { getCodeFileIcon } from '@mantinex/dev-icons';
2 | import classes from './DemoCode.module.scss';
3 | import { CodeHighlightTabs, CodeHighlightTabsCode } from '@mantine/code-highlight';
4 |
5 |
6 | export interface DemoCodeProps {
7 | code?: string | CodeHighlightTabsCode | CodeHighlightTabsCode[];
8 | defaultExpanded?: boolean;
9 | }
10 |
11 | export function DemoCode({ code, defaultExpanded = true }: DemoCodeProps) {
12 | const _code: CodeHighlightTabsCode | CodeHighlightTabsCode[] | undefined =
13 | typeof code === 'string' ? { code, fileName: 'Demo.tsx', language: 'tsx' } : code;
14 | return _code ? (
15 |
22 | ) : null;
23 | }
24 |
--------------------------------------------------------------------------------
/src/feature/blocks/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 | withColor?: boolean;
15 | dimmed?: boolean;
16 | canvas: { center: boolean; maxWidth?: number };
17 | category: string;
18 | title: string;
19 | props?: Record;
20 | }
21 |
22 | export interface UiComponent {
23 | component: string;
24 | slug: string;
25 | code: { fileName: string; language: string; code: string }[];
26 | attributes: CanvasAttributes;
27 | }
28 |
29 | export interface ComponentInfo {
30 | component: string;
31 | slug: string;
32 | code: { fileName: string; language: string; code: string }[];
33 | attributes: any;
34 | }
35 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/data/_bubble-data.ts:
--------------------------------------------------------------------------------
1 | export const data = [
2 | { hour: '08:00', index: 1, value: 150 },
3 | { hour: '10:00', index: 1, value: 180 },
4 | { hour: '12:00', index: 1, value: 280 },
5 | { hour: '14:00', index: 1, value: 120 },
6 | { hour: '16:00', index: 1, value: 380 },
7 | { hour: '18:00', index: 1, value: 400 },
8 | { hour: '20:00', index: 1, value: 180 },
9 | { hour: '22:00', index: 1, value: 100 },
10 | ];
11 |
12 | export const dataCode = `
13 | export const data = [
14 | { hour: '08:00', index: 1, value: 150 },
15 | { hour: '10:00', index: 1, value: 166 },
16 | { hour: '12:00', index: 1, value: 170 },
17 | { hour: '14:00', index: 1, value: 150 },
18 | { hour: '16:00', index: 1, value: 200 },
19 | { hour: '18:00', index: 1, value: 400 },
20 | { hour: '20:00', index: 1, value: 100 },
21 | { hour: '22:00', index: 1, value: 160 },
22 | ];
23 | `;
24 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/data-display/color-swatch-demo.tsx:
--------------------------------------------------------------------------------
1 | import { ColorSwatch, Group } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { ColorSwatch, Group } from '@mantine/core';
6 |
7 | function Demo() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 | );
15 | }
16 | `;
17 |
18 | function Demo() {
19 | return (
20 |
21 |
22 |
23 |
24 |
25 | );
26 | }
27 |
28 | export const colorSwatchDemo: MantineDemo = {
29 | type: 'code',
30 | component: Demo,
31 | centered: true,
32 | code,
33 | };
34 |
--------------------------------------------------------------------------------
/src/components/ui/navbar/navbar.tsx:
--------------------------------------------------------------------------------
1 | import { ScrollArea } from '@mantine/core';
2 | import { useState } from 'react';
3 | import NavbarLinksGroup from './navbar-links-group';
4 | import classes from "./navbar.module.scss";
5 |
6 | export interface NavbarProps {
7 | label: string;
8 | initiallyOpened?: boolean;
9 | links?: { label: string; value: string}[];
10 | }
11 |
12 | export default function Navbar({menu}: {menu: NavbarProps[]}) {
13 | const [selected, setSelected] = useState(menu?.[0]?.links?.[0].value ?? '');
14 |
15 | const menuItems = menu.map((item) => );
16 |
17 | return (
18 |
23 | );
24 | }
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/components/custom/blocks/coming-soon/coming-soon.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | padding: 4rem 1rem;
3 | }
4 |
5 | .title {
6 | font-size: 8rem;
7 | font-weight: 800;
8 | background: linear-gradient(135deg, var(--mantine-color-blue-9) 0%, var(--mantine-color-indigo-9) 100%);
9 | margin-bottom: 1.5rem;
10 | }
11 |
12 | .socialButton {
13 | width: 48px;
14 | height: 48px;
15 | border-radius: 24px;
16 | padding: 0;
17 | display: flex;
18 | align-items: center;
19 | justify-content: center;
20 | }
21 |
22 | .socialButton:hover {
23 | transform: translateY(-2px);
24 | }
25 |
26 | .socialIcon {
27 | width: 24px;
28 | height: 24px;
29 | color: var(--mantine-color-dimmed);
30 | }
31 |
32 | .successMessage {
33 | text-align: center;
34 | color: var(--mantine-primary-color-7);
35 | font-size: 1.25rem;
36 | font-weight: 500;
37 | padding: 1rem;
38 | border-radius: var(--mantine-radius-md);
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/combobox/select-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Select } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { inputControls } from '../../../../utils/input-controls';
4 |
5 | const code = `
6 | import { Select } from '@mantine/core';
7 |
8 |
9 | function Demo() {
10 | return (
11 |
16 | );
17 | }
18 | `;
19 |
20 | function Wrapper(props: any) {
21 | return (
22 |
27 | );
28 | }
29 |
30 | export const selectDemo: MantineDemo = {
31 | type: 'configurator',
32 | component: Wrapper,
33 | code,
34 | centered: true,
35 | maxWidth: 340,
36 | controls: inputControls,
37 | };
38 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from "@eslint/js";
2 | import globals from "globals";
3 | import reactHooks from "eslint-plugin-react-hooks";
4 | import reactRefresh from "eslint-plugin-react-refresh";
5 | import tseslint from "typescript-eslint";
6 | import eslintConfigPrettier from "eslint-config-prettier";
7 |
8 | export default tseslint.config(
9 | { ignores: ["dist"] },
10 | {
11 | extends: [js.configs.recommended, ...tseslint.configs.recommended],
12 | files: ["**/*.{ts,tsx}"],
13 | languageOptions: {
14 | ecmaVersion: 2020,
15 | globals: globals.browser,
16 | },
17 | plugins: {
18 | "react-hooks": reactHooks,
19 | "react-refresh": reactRefresh,
20 | },
21 | rules: {
22 | ...reactHooks.configs.recommended.rules,
23 | "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
24 | "@typescript-eslint/no-explicit-any": 0,
25 | },
26 | },
27 | eslintConfigPrettier
28 | );
29 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/combobox/multi-select-demo.tsx:
--------------------------------------------------------------------------------
1 | import { MultiSelect } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { inputControls } from '../../../../utils/input-controls';
4 |
5 | const code = `
6 | import { MultiSelect } from '@mantine/core';
7 |
8 |
9 | function Demo() {
10 | return (
11 |
16 | );
17 | }
18 | `;
19 |
20 | function Wrapper(props: any) {
21 | return (
22 |
27 | );
28 | }
29 |
30 | export const multiSelectDemo: MantineDemo = {
31 | type: 'configurator',
32 | component: Wrapper,
33 | code,
34 | centered: true,
35 | maxWidth: 340,
36 | controls: inputControls,
37 | };
38 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/rating-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Rating, RatingProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Rating } from '@mantine/core';
6 |
7 | function Demo() {
8 | return
9 | }
10 | `;
11 |
12 | function Wrapper(props: RatingProps) {
13 | return ;
14 | }
15 |
16 | export const ratingDemo: MantineDemo = {
17 | type: 'configurator',
18 | component: Wrapper,
19 | code,
20 | centered: true,
21 | controls: [
22 | { prop: 'color', type: 'color', initialValue: "yellow", libraryValue: "yellow" },
23 | { prop: 'size', type: 'size', initialValue: 'md', libraryValue: 'md' },
24 | { prop: 'count', type: 'number', initialValue: 5, libraryValue: 5, min: 1, max: 8 },
25 | { prop: 'highlightSelectedOnly', type: 'boolean', initialValue: false, libraryValue: false },
26 | ],
27 | };
28 |
--------------------------------------------------------------------------------
/js/scripts/generateStyles.cjs:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const path = require("path");
3 |
4 | function generateCssStyles(location, outputFileName) {
5 | // Read the content of the CSS file
6 | const fileContent = fs.readFileSync(location, "utf-8");
7 |
8 | // Format the content as a TypeScript export statement
9 | const tsContent = `export const ${outputFileName} = \`${fileContent}\`;`;
10 |
11 | // Define the output directory
12 | const outputDir = path.join(__dirname, `../../src/themes/generated/${outputFileName}.ts`);
13 |
14 | // Write the final content to the file
15 | fs.writeFileSync(outputDir, tsContent, "utf-8");
16 | console.log(`CSS styles file created: ${outputDir}`);
17 | }
18 |
19 | generateCssStyles(
20 | path.join(__dirname, "../../src/styles/shadcn-styles.css"),
21 | "generatedShadcnCssStyles"
22 | );
23 | generateCssStyles(
24 | path.join(__dirname, "../../src/styles/mantine-styles.css"),
25 | "generatedMantineCssStyles"
26 | );
27 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/combobox/autocomplete-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Autocomplete } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { inputControls } from '../../../../utils/input-controls';
4 |
5 | const code = `
6 | import { Autocomplete } from '@mantine/core';
7 |
8 |
9 | function Demo() {
10 | return (
11 |
16 | );
17 | }
18 | `;
19 |
20 | function Wrapper(props: any) {
21 | return (
22 |
27 | );
28 | }
29 |
30 | export const autocompleteDemo: MantineDemo = {
31 | type: 'configurator',
32 | component: Wrapper,
33 | code,
34 | centered: true,
35 | maxWidth: 340,
36 | controls: inputControls,
37 | };
38 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/ConfiguratorBoolean.control.tsx:
--------------------------------------------------------------------------------
1 | import { BoxProps, ElementProps, Switch } from '@mantine/core';
2 | import { getControlLabel } from './get-control-label';
3 | import { ConfiguratorControl } from './types';
4 |
5 | export type ConfiguratorBooleanControlOptions = ConfiguratorControl<
6 | 'boolean',
7 | { initialValue: boolean }
8 | >;
9 |
10 | export interface ConfiguratorBooleanControlProps
11 | extends BoxProps,
12 | ElementProps<'input', 'onChange' | 'value' | 'size'> {
13 | value: boolean;
14 | onChange: (value: boolean) => void;
15 | prop: string;
16 | }
17 |
18 | export function ConfiguratorBooleanControl({
19 | value,
20 | onChange,
21 | prop,
22 | ...others
23 | }: ConfiguratorBooleanControlProps) {
24 | return (
25 | onChange(event.currentTarget.checked)}
28 | label={getControlLabel(prop)}
29 | {...others}
30 | />
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoColumns/DemoColumns.module.css:
--------------------------------------------------------------------------------
1 | .columns {
2 | display: flex;
3 |
4 | @media (max-width: 55em) {
5 | flex-direction: column;
6 | }
7 | }
8 |
9 | .controls {
10 | flex: 0 0 250px;
11 | border-left: 1px solid var(--demo-border);
12 | padding: 4px;
13 | padding-bottom: var(--mantine-spacing-xs);
14 |
15 | @mixin rtl {
16 | border-left: none;
17 | border-right: 1px solid var(--demo-border);
18 | }
19 |
20 | @media (max-width: 55em) {
21 | flex: unset;
22 | border-left: none;
23 | border-right: none !important;
24 | border-top: 1px solid var(--demo-border);
25 | }
26 | }
27 |
28 | .header {
29 | padding-top: calc(var(--mantine-spacing-md) - 4px);
30 | margin-left: -4px;
31 | margin-right: -4px;
32 | border-bottom: 1px solid var(--demo-border);
33 | padding-left: var(--mantine-spacing-md);
34 | padding-right: var(--mantine-spacing-md);
35 | padding-bottom: var(--mantine-spacing-xs);
36 | margin-bottom: var(--mantine-spacing-xs);
37 | }
38 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/ConfiguratorString.control.tsx:
--------------------------------------------------------------------------------
1 | import { BoxProps, ElementProps, TextInput } from '@mantine/core';
2 | import { getControlLabel } from './get-control-label';
3 | import { ConfiguratorControl } from './types';
4 |
5 | export type ConfiguratorStringControlOptions = ConfiguratorControl<
6 | 'string',
7 | { initialValue: string }
8 | >;
9 |
10 | export interface ConfiguratorStringControlProps
11 | extends BoxProps,
12 | ElementProps<'input', 'onChange' | 'value' | 'size'> {
13 | value: string;
14 | onChange: (value: string) => void;
15 | prop: string;
16 | }
17 |
18 | export function ConfiguratorStringControl({
19 | value,
20 | onChange,
21 | prop,
22 | ...others
23 | }: ConfiguratorStringControlProps) {
24 | return (
25 | onChange(event.currentTarget.value)}
28 | label={getControlLabel(prop)}
29 | placeholder="Enter prop value"
30 | {...others}
31 | />
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/combobox/tags-input-demo.tsx:
--------------------------------------------------------------------------------
1 | import { TagsInput } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { inputControls } from '../../../../utils/input-controls';
4 |
5 | const code = `
6 | import { TagsInput } from '@mantine/core';
7 |
8 |
9 | function Demo() {
10 | return (
11 |
17 | );
18 | }
19 | `;
20 |
21 | function Wrapper(props: any) {
22 | return (
23 |
29 | );
30 | }
31 |
32 | export const tagsInputDemo: MantineDemo = {
33 | type: 'configurator',
34 | component: Wrapper,
35 | code,
36 | centered: true,
37 | maxWidth: 340,
38 | controls: inputControls,
39 | };
40 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/data-display/badge-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Badge } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Badge } from '@mantine/core';
6 |
7 | function Demo() {
8 | return Badge;
9 | }
10 | `;
11 |
12 | function Wrapper(props: any) {
13 | return Badge;
14 | }
15 |
16 | export const badgeDemo: MantineDemo = {
17 | type: 'configurator',
18 | component: Wrapper,
19 | code,
20 | centered: true,
21 | controls: [
22 | {
23 | prop: 'variant',
24 | type: 'select',
25 | initialValue: 'filled',
26 | libraryValue: 'filled',
27 | data: ['filled', 'light', 'outline', 'dot', 'transparent', 'default', 'white'],
28 | },
29 | { type: 'color', prop: 'color', initialValue: '', libraryValue: '' },
30 | { type: 'size', prop: 'size', initialValue: 'md', libraryValue: 'md' },
31 | { type: 'size', prop: 'radius', initialValue: 'xl', libraryValue: 'xl' },
32 | ],
33 | };
34 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/typography/highlight-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Highlight, HighlightProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: HighlightProps) {
5 | return ;
6 | }
7 |
8 | const code = `
9 | import { Highlight } from '@mantine/core';
10 |
11 | function Demo() {
12 | return (
13 |
14 | {{children}}
15 |
16 | );
17 | }
18 | `;
19 |
20 | export const highlightDemo: MantineDemo = {
21 | type: 'configurator',
22 | component: Wrapper,
23 | code,
24 | centered: true,
25 | maxWidth: '100%',
26 | controls: [
27 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
28 | { prop: 'highlight', type: 'string', initialValue: 'this', libraryValue: null },
29 | {
30 | prop: 'children',
31 | type: 'string',
32 | initialValue: 'Highlight This, definitely THIS and also this!',
33 | libraryValue: null,
34 | },
35 | ],
36 | };
37 |
--------------------------------------------------------------------------------
/src/components/ui/color-scheme-switch/color-scheme-switch.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | ActionIcon,
3 | useComputedColorScheme,
4 | useMantineColorScheme,
5 | } from "@mantine/core";
6 |
7 | import { IconSun, IconMoon } from "@tabler/icons-react";
8 | import cx from "clsx";
9 | import classes from "./color-scheme-switch.module.css";
10 |
11 | const ColorSchemeSwitch = () => {
12 | const { setColorScheme } = useMantineColorScheme();
13 | const computedColorScheme = useComputedColorScheme("light", {
14 | getInitialValueInEffect: true,
15 | });
16 |
17 | return (
18 |
19 |
21 | setColorScheme(computedColorScheme === "light" ? "dark" : "light")
22 | }
23 | variant="default"
24 | size="lg"
25 | aria-label="Toggle color scheme"
26 | >
27 |
28 |
29 |
30 |
31 | );
32 | };
33 |
34 | export default ColorSchemeSwitch;
35 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/buttons/button-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@mantine/core';
2 | import { interactiveVariantsControl } from '../../../../utils/variants-data';
3 | import { MantineDemo } from '../../../mantine/demo';
4 |
5 | const code = `
6 | import { Button } from '@mantine/core';
7 |
8 | function Demo() {
9 | return ;
10 | }
11 | `;
12 |
13 | function Wrapper(props: any) {
14 | return ;
15 | }
16 |
17 | export const buttonDemo: MantineDemo = {
18 | type: 'configurator',
19 | component: Wrapper,
20 | code,
21 | centered: true,
22 | controls: [
23 | interactiveVariantsControl,
24 | { type: 'color', prop: 'color', initialValue: "", libraryValue: "" },
25 | { type: 'size', prop: 'size', initialValue: 'sm', libraryValue: 'sm' },
26 | { type: 'size', prop: 'radius', initialValue: 'sm', libraryValue: 'sm' },
27 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
28 | { prop: 'loading', type: 'boolean', initialValue: false, libraryValue: false },
29 | ],
30 | };
--------------------------------------------------------------------------------
/src/components/custom/components-demo/navigation/pagination-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Pagination } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: any) {
5 | return ;
6 | }
7 |
8 | const code = `
9 | import { Pagination } from '@mantine/core';
10 |
11 | function Demo() {
12 | return ;
13 | }
14 | `;
15 |
16 | export const paginationDemo: MantineDemo = {
17 | type: 'configurator',
18 | component: Wrapper,
19 | code,
20 | centered: true,
21 | controls: [
22 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
23 | { prop: 'size', type: 'size', initialValue: 'md', libraryValue: 'md' },
24 | { prop: 'radius', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
25 | { prop: 'withControls', type: 'boolean', initialValue: true, libraryValue: true },
26 | { prop: 'withEdges', type: 'boolean', initialValue: false, libraryValue: false },
27 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
28 | ],
29 | };
30 |
--------------------------------------------------------------------------------
/src/feature/blocks/components/shell/shell.tsx:
--------------------------------------------------------------------------------
1 | import { AppShell, Container, Group, RemoveScroll } from "@mantine/core";
2 | import { ColorSchemeControl, HeaderControls } from "@mantinex/mantine-header";
3 |
4 | import classes from "./shell.module.scss";
5 |
6 | interface ShellProps {
7 | children: React.ReactNode;
8 | }
9 |
10 | const Shell = ({ children }: ShellProps) => {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 | {/* */}
19 |
20 |
21 |
22 |
23 |
24 | {children}
25 |
26 |
27 | );
28 | };
29 |
30 | export default Shell;
31 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoArea/DemoArea.tsx:
--------------------------------------------------------------------------------
1 | import { Box, rem } from '@mantine/core';
2 | import classes from './DemoArea.module.css';
3 |
4 | export interface DemoAreaProps {
5 | children?: React.ReactNode;
6 | withPadding?: boolean;
7 | centered?: boolean;
8 | maxWidth?: number | string;
9 | minHeight?: number | string;
10 | dimmed?: boolean;
11 | striped?: boolean;
12 | }
13 |
14 | export function DemoArea({
15 | withPadding = true,
16 | centered,
17 | maxWidth,
18 | minHeight,
19 | children,
20 | dimmed,
21 | striped,
22 | }: DemoAreaProps) {
23 | return (
24 |
34 | {children}
35 |
36 | );
37 | }
38 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/ConfiguratorNumber.control.tsx:
--------------------------------------------------------------------------------
1 | import { BoxProps, ElementProps, Input, Slider } from '@mantine/core';
2 | import { getControlLabel } from './get-control-label';
3 | import { ConfiguratorControl } from './types';
4 |
5 | export type ConfiguratorNumberControlOptions = ConfiguratorControl<
6 | 'number',
7 | { initialValue: number; min?: number; max?: number; step?: number }
8 | >;
9 |
10 | export interface ConfiguratorNumberControlProps extends BoxProps, ElementProps<'div', 'onChange'> {
11 | value: number;
12 | onChange: (value: number) => void;
13 | prop: string;
14 | step?: number;
15 | min?: number;
16 | max?: number;
17 | }
18 |
19 | export function ConfiguratorNumberControl({
20 | value,
21 | onChange,
22 | prop,
23 | step,
24 | min,
25 | max,
26 | ...others
27 | }: ConfiguratorNumberControlProps) {
28 | return (
29 |
30 |
31 |
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/typography/title-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Title } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Title } from '@mantine/core';
6 |
7 | function Demo() {
8 | return (
9 | <>
10 | This is h1 title
11 | This is h2 title
12 | This is h3 title
13 | This is h4 title
14 | This is h5 title
15 | This is h6 title
16 | >
17 | );
18 | }
19 | `;
20 |
21 | function Demo() {
22 | return (
23 | <>
24 | This is h1 title
25 | This is h2 title
26 | This is h3 title
27 | This is h4 title
28 | This is h5 title
29 | This is h6 title
30 | >
31 | );
32 | }
33 |
34 | export const titleDemo: MantineDemo = {
35 | type: 'code',
36 | code,
37 | component: Demo,
38 | };
39 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/navigation/anchor-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Anchor } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Anchor } from '@mantine/core';
6 |
7 |
8 | function Demo() {
9 | return (
10 |
11 | Anchor component
12 |
13 | );
14 | }
15 | `;
16 |
17 | function Wrapper(props: any) {
18 | return (
19 |
20 | Anchor component
21 |
22 | );
23 | }
24 |
25 | export const anchorDemo: MantineDemo = {
26 | type: 'configurator',
27 | component: Wrapper,
28 | code,
29 | centered: true,
30 | maxWidth: 340,
31 | controls: [
32 | {
33 | prop: 'underline',
34 | type: 'segmented',
35 | data: [
36 | { value: 'always', label: 'Always' },
37 | { value: 'hover', label: 'Hover' },
38 | { value: 'never', label: 'Never' },
39 | ],
40 | initialValue: 'always',
41 | libraryValue: 'always',
42 | },
43 | ]
44 | };
45 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 RubixCube Innovations
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/ConfiguratorSelect.control.tsx:
--------------------------------------------------------------------------------
1 | import { BoxProps, ElementProps, NativeSelect } from '@mantine/core';
2 | import { getControlLabel } from './get-control-label';
3 | import { SelectData, transformSelectData } from './transform-select-data';
4 | import { ConfiguratorControl } from './types';
5 |
6 | export type ConfiguratorSelectControlOptions = ConfiguratorControl<
7 | 'select',
8 | { data: SelectData; initialValue: string }
9 | >;
10 |
11 | export interface ConfiguratorSelectControlProps
12 | extends BoxProps,
13 | ElementProps<'select', 'onChange' | 'value' | 'size'> {
14 | value: string;
15 | data: SelectData;
16 | onChange: (value: string) => void;
17 | prop: string;
18 | }
19 |
20 | export function ConfiguratorSelectControl({
21 | value,
22 | onChange,
23 | prop,
24 | data,
25 | ...others
26 | }: ConfiguratorSelectControlProps) {
27 | return (
28 | onChange(event.currentTarget.value)}
31 | label={getControlLabel(prop)}
32 | data={transformSelectData(data)}
33 | {...others}
34 | />
35 | );
36 | }
37 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/bubble-chart-demo.tsx:
--------------------------------------------------------------------------------
1 | import { BubbleChart } from '@mantine/charts';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { data, dataCode } from './data/_bubble-data';
4 |
5 | const code = `
6 | import { BubbleChart } from '@mantine/charts';
7 | import { data } from './data';
8 |
9 |
10 | function Demo() {
11 | return (
12 |
19 | );
20 | }
21 | `;
22 |
23 | function Demo(props: any) {
24 | return (
25 |
32 | );
33 | }
34 |
35 | export const bubbleChartDemo: MantineDemo = {
36 | type: 'configurator',
37 | component: Demo,
38 | code: [
39 | { code, language: 'tsx', fileName: 'Demo.tsx' },
40 | { code: dataCode, language: 'tsx', fileName: 'data.ts' },
41 | ],
42 | controls: [{ type: 'color', prop: 'color', initialValue: '', libraryValue: '' }],
43 | };
44 |
--------------------------------------------------------------------------------
/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/combobox/pills-input-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Pill, PillsInput } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { inputControls } from '../../../../utils/input-controls';
4 |
5 | const code = `
6 | import { PillsInput, Pill } from '@mantine/core';
7 |
8 |
9 | function Demo() {
10 | return (
11 |
14 |
15 | React
16 | Vue
17 | Svelte
18 |
19 |
20 |
21 | );
22 | }
23 | `;
24 |
25 | function Wrapper(props: any) {
26 | return (
27 |
28 |
29 | React
30 | Vue
31 | Svelte
32 |
33 |
34 |
35 | );
36 | }
37 |
38 | export const pillsInputDemo: MantineDemo = {
39 | type: 'configurator',
40 | component: Wrapper,
41 | code,
42 | centered: true,
43 | maxWidth: 440,
44 | controls: inputControls,
45 | };
46 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/feedback/progress-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Progress } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Progress } from '@mantine/core';
6 |
7 | function Demo() {
8 | return ;
9 | }
10 | `;
11 |
12 | function Demo(props: any) {
13 | return ;
14 | }
15 |
16 | export const progressDemo: MantineDemo = {
17 | type: 'configurator',
18 | component: Demo,
19 | code,
20 | centered: true,
21 | maxWidth: 400,
22 | controls: [
23 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
24 | { prop: 'radius', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
25 | { prop: 'size', type: 'size', initialValue: 'md', libraryValue: 'md' },
26 | {
27 | prop: 'value',
28 | type: 'number',
29 | initialValue: 50,
30 | max: 100,
31 | min: 0,
32 | step: 10,
33 | libraryValue: '__',
34 | },
35 | { prop: 'striped', type: 'boolean', initialValue: false, libraryValue: false },
36 | { prop: 'animated', type: 'boolean', initialValue: false, libraryValue: false },
37 | ],
38 | };
39 |
--------------------------------------------------------------------------------
/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/overlays/popover-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Popover, Text } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Popover, Text, Button } from '@mantine/core';
6 |
7 | function Demo() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 | This is uncontrolled popover, it is opened when button is clicked
15 |
16 |
17 | );
18 | }
19 | `;
20 |
21 | function Demo() {
22 | return (
23 |
24 |
25 |
26 |
27 |
28 | This is uncontrolled popover, it is opened when button is clicked
29 |
30 |
31 | );
32 | }
33 |
34 | export const popoverDemo: MantineDemo = {
35 | type: 'code',
36 | code,
37 | centered: true,
38 | component: Demo,
39 | };
40 |
--------------------------------------------------------------------------------
/src/components/ui/chart-tooltip.tsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-explicit-any */
2 | import { Flex, Paper, Stack, Text } from "@mantine/core";
3 |
4 | interface ChartTooltipProps {
5 | label: string;
6 | payload: Record[] | undefined;
7 | }
8 |
9 | export function ChartTooltip({ payload }: ChartTooltipProps) {
10 | if (!payload) return null;
11 |
12 | return (
13 |
14 |
15 | {payload.map((item: any) => (
16 |
17 |
26 | {item.name}
27 |
28 |
34 | {item?.value}
35 |
36 |
37 | ))}
38 |
39 |
40 | );
41 | }
42 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/index.ts:
--------------------------------------------------------------------------------
1 | export { ConfiguratorBooleanControl } from './ConfiguratorBoolean.control';
2 | export { ConfiguratorSegmentedControl } from './ConfiguratorSegmented.control';
3 | export { ConfiguratorColorControl } from './ConfiguratorColor.control';
4 | export { ConfiguratorStringControl } from './ConfiguratorString.control';
5 | export { ConfiguratorSelectControl } from './ConfiguratorSelect.control';
6 | export { ConfiguratorSizeControl } from './ConfiguratorSize.control';
7 | export { ConfiguratorNumberControl } from './ConfiguratorNumber.control';
8 |
9 | export type { ConfiguratorBooleanControlOptions } from './ConfiguratorBoolean.control';
10 | export type { ConfiguratorSegmentedControlOptions } from './ConfiguratorSegmented.control';
11 | export type { ConfiguratorColorControlOptions } from './ConfiguratorColor.control';
12 | export type { ConfiguratorStringControlOptions } from './ConfiguratorString.control';
13 | export type { ConfiguratorSelectControlOptions } from './ConfiguratorSelect.control';
14 | export type { ConfiguratorSizeControlOptions } from './ConfiguratorSize.control';
15 | export type { ConfiguratorNumberControlOptions } from './ConfiguratorNumber.control';
16 |
--------------------------------------------------------------------------------
/src/styles/index.scss:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @import "./_mantine.scss";
6 |
7 | :root {
8 | color-scheme: var(--mantine-color-scheme);
9 | font-family: var(--mantine-font-family);
10 | width: 100%;
11 | }
12 |
13 | body {
14 | margin: 0;
15 |
16 | font-size: var(--mantine-font-size-md);
17 | line-height: var(--mantine-line-height);
18 | background-color: var(--mantine-color-body);
19 | color: var(--mantine-color-text);
20 |
21 | -webkit-font-smoothing: var(--mantine-webkit-font-smoothing);
22 | -moz-osx-font-smoothing: var(--mantine-moz-font-smoothing);
23 |
24 | opacity: 0;
25 | transition: opacity 0.2s ease-in;
26 | }
27 |
28 | body.rendered {
29 | opacity: 1;
30 | }
31 |
32 | *,
33 | *::before,
34 | *::after {
35 | box-sizing: border-box;
36 | }
37 |
38 | input,
39 | button,
40 | textarea,
41 | select {
42 | font: inherit;
43 | }
44 |
45 | button,
46 | select {
47 | text-transform: none;
48 | }
49 |
50 | @media (prefers-color-scheme: light) {
51 | :root {
52 | color: #213547;
53 | background-color: #ffffff;
54 | }
55 | a:hover {
56 | color: #747bff;
57 | }
58 | button {
59 | background-color: #f9f9f9;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/utils/themeTemplate.ts:
--------------------------------------------------------------------------------
1 | export const generateThemeTemplate = (theme: string, variableResolver: string) => {
2 | const template = `
3 | import {
4 | alpha,
5 | Card,
6 | Checkbox,
7 | Code,
8 | Container,
9 | createTheme,
10 | CSSVariablesResolver,
11 | defaultVariantColorsResolver,
12 | Divider,
13 | Input,
14 | mergeThemeOverrides,
15 | Modal,
16 | Paper,
17 | Popover,
18 | rem,
19 | Switch,
20 | Table,
21 | Tooltip,
22 | } from "@mantine/core";
23 |
24 | import { Spotlight } from "@mantine/spotlight";
25 |
26 | const CONTAINER_SIZES: Record = {
27 | xxs: rem(200),
28 | xs: rem(300),
29 | sm: rem(400),
30 | md: rem(500),
31 | lg: rem(600),
32 | xl: rem(1400),
33 | xxl: rem(1600),
34 | };
35 |
36 | const theme = createTheme({
37 | /** Put your mantine theme override here */
38 | ${theme}
39 | });
40 |
41 | ${generateVariableResolverTemplate(variableResolver)}
42 |
43 | `;
44 |
45 | return template;
46 | };
47 |
48 | export const generateVariableResolverTemplate = (value: any) => {
49 | const template = `
50 | export const mantineCssVariableResolver: CSSVariablesResolver = () => ({
51 | ${value}
52 | });
53 | `;
54 |
55 | return template;
56 | };
57 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/navigation/stepper-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Stepper, StepperProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: Partial) {
5 | return (
6 |
7 |
8 |
9 |
10 | );
11 | }
12 |
13 | const code = `
14 | import { Stepper } from '@mantine/core';
15 |
16 | function Demo() {
17 | return (
18 |
19 |
20 |
21 |
22 | );
23 | }
24 | `;
25 |
26 | export const stepperDemo: MantineDemo = {
27 | type: 'configurator',
28 | component: Wrapper,
29 | code,
30 | centered: true,
31 | maxWidth: '100%',
32 | controls: [
33 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
34 | { prop: 'radius', type: 'size', initialValue: 'xl', libraryValue: 'xl' },
35 | { prop: 'size', type: 'size', initialValue: 'md', libraryValue: 'md' },
36 | ],
37 | };
38 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/overlays/modal-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Modal } from '@mantine/core';
2 | import { useDisclosure } from '@mantine/hooks';
3 | import { AuthenticationForm } from './authentication-form';
4 | import { MantineDemo } from '../../../mantine/demo';
5 |
6 | const code = `
7 | import { useDisclosure } from '@mantine/hooks';
8 | import { Modal, Button } from '@mantine/core';
9 |
10 | function Demo() {
11 | const [opened, { open, close }] = useDisclosure(false);
12 |
13 | return (
14 | <>
15 |
16 | {/* Modal content */}
17 |
18 |
19 |
20 | >
21 | );
22 | }
23 | `;
24 |
25 | function Demo() {
26 | const [opened, { open, close }] = useDisclosure(false);
27 |
28 | return (
29 | <>
30 |
31 |
32 |
33 |
34 |
35 | >
36 | );
37 | }
38 |
39 | export const modalDemo: MantineDemo = {
40 | type: 'code',
41 | code,
42 | centered: true,
43 | component: Demo,
44 | };
45 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/overlays/drawer-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Drawer } from '@mantine/core';
2 | import { useDisclosure } from '@mantine/hooks';
3 | import { MantineDemo } from '../../../mantine/demo';
4 | import { AuthenticationForm } from './authentication-form';
5 |
6 | const code = `
7 | import { useDisclosure } from '@mantine/hooks';
8 | import { Drawer, Button } from '@mantine/core';
9 |
10 | function Demo() {
11 | const [opened, { open, close }] = useDisclosure(false);
12 |
13 | return (
14 | <>
15 |
16 | {/* Drawer content */}
17 |
18 |
19 |
20 | >
21 | );
22 | }
23 | `;
24 |
25 | function Demo() {
26 | const [opened, { open, close }] = useDisclosure(false);
27 |
28 | return (
29 | <>
30 |
31 |
32 |
33 |
34 |
35 | >
36 | );
37 | }
38 |
39 | export const drawerDemo: MantineDemo = {
40 | type: 'code',
41 | code,
42 | centered: true,
43 | component: Demo,
44 | };
45 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // "files": [],
3 | // "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }],
4 | "compilerOptions": {
5 | "target": "ES2020",
6 | "useDefineForClassFields": true,
7 | "lib": [
8 | "ES2020",
9 | "DOM",
10 | "DOM.Iterable"
11 | ],
12 | "module": "ESNext",
13 | "esModuleInterop": true,
14 | "skipLibCheck": true,
15 | "moduleResolution": "bundler",
16 | "allowImportingTsExtensions": true,
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "noEmit": true,
20 | "jsx": "preserve",
21 | "strict": true,
22 | "noUnusedLocals": true,
23 | "noUnusedParameters": true,
24 | "noFallthroughCasesInSwitch": true,
25 | "allowJs": true,
26 | "forceConsistentCasingInFileNames": true,
27 | "incremental": true,
28 | "plugins": [
29 | {
30 | "name": "next"
31 | }
32 | ],
33 | "baseUrl": ".",
34 | "paths": {
35 | "@/*": [
36 | "src/*"
37 | ]
38 | }
39 | },
40 | "include": [
41 | "./dist/types/**/*.ts",
42 | "./next-env.d.ts",
43 | "./src",
44 | ".next/types/**/*.ts"
45 | ],
46 | "exclude": [
47 | "./node_modules"
48 | ]
49 | }
50 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/scatter-chart-demo.tsx:
--------------------------------------------------------------------------------
1 | import { ScatterChart } from '@mantine/charts';
2 | import { doubleData, doubleDataCode } from './data/_scatter-data';
3 | import { MantineDemo } from '../../../mantine/demo';
4 |
5 | const code = `
6 | import { ScatterChart } from '@mantine/charts';
7 | import { data } from './data';
8 |
9 | function Demo() {
10 | return (
11 |
20 | );
21 | }
22 | `;
23 |
24 | function Demo() {
25 | return (
26 |
35 | );
36 | }
37 |
38 | export const scatterChartDemo: MantineDemo = {
39 | type: 'code',
40 | component: Demo,
41 | code: [
42 | { code, language: 'tsx', fileName: 'Demo.tsx' },
43 | { code: doubleDataCode, language: 'tsx', fileName: 'data.ts' },
44 | ],
45 | };
46 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/Demo/Demo.tsx:
--------------------------------------------------------------------------------
1 | import { CodeDemo, CodeDemoProps } from '../CodeDemo/CodeDemo';
2 | import { ConfiguratorDemo, ConfiguratorDemoProps } from '../ConfiguratorDemo/ConfiguratorDemo';
3 | import { StylesApiDemo, StylesApiDemoProps } from '../StylesApiDemo/StylesApiDemo';
4 |
5 | interface DemoComponent {
6 | component: React.FC;
7 | }
8 |
9 | export type MantineDemo =
10 | | ({ type: 'code' } & DemoComponent & CodeDemoProps)
11 | | ({ type: 'configurator' } & DemoComponent & ConfiguratorDemoProps)
12 | | ({ type: 'styles-api' } & DemoComponent & StylesApiDemoProps);
13 |
14 | interface DemoProps {
15 | data: MantineDemo;
16 | }
17 |
18 | export function Demo({ data }: DemoProps) {
19 | switch (data.type) {
20 | case 'code':
21 | return (
22 |
23 |
24 |
25 | );
26 | case 'configurator':
27 | return (
28 |
29 |
30 |
31 | );
32 | case 'styles-api':
33 | return (
34 |
35 |
36 |
37 | );
38 | default:
39 | return null;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/app/sitemap.ts:
--------------------------------------------------------------------------------
1 | import { MetadataRoute } from 'next'
2 |
3 | // Configure for static export
4 | export const dynamic = 'force-static'
5 | export const revalidate = 3600 // Revalidate every hour
6 |
7 | export default function sitemap(): MetadataRoute.Sitemap {
8 | const baseUrl = 'https://mantinehub.com'
9 |
10 | return [
11 | {
12 | url: baseUrl,
13 | lastModified: new Date(),
14 | changeFrequency: 'daily',
15 | priority: 1,
16 | },
17 | {
18 | url: `${baseUrl}/blocks`,
19 | lastModified: new Date(),
20 | changeFrequency: 'daily',
21 | priority: 0.9,
22 | },
23 | {
24 | url: `${baseUrl}/about`,
25 | lastModified: new Date(),
26 | changeFrequency: 'monthly',
27 | priority: 0.6,
28 | },
29 | {
30 | url: `${baseUrl}/how-to-use`,
31 | lastModified: new Date(),
32 | changeFrequency: 'monthly',
33 | priority: 0.6,
34 | },
35 | {
36 | url: `${baseUrl}/playground`,
37 | lastModified: new Date(),
38 | changeFrequency: 'monthly',
39 | priority: 0.7,
40 | },
41 | {
42 | url: `${baseUrl}/feedback`,
43 | lastModified: new Date(),
44 | changeFrequency: 'monthly',
45 | priority: 0.5,
46 | },
47 | ]
48 | }
--------------------------------------------------------------------------------
/_mantine.scss:
--------------------------------------------------------------------------------
1 | @use "sass:math";
2 |
3 | // Define variables for your breakpoints,
4 | // values must be the same as in your theme
5 | $mantine-breakpoint-xs: "36em";
6 | $mantine-breakpoint-sm: "48em";
7 | $mantine-breakpoint-md: "62em";
8 | $mantine-breakpoint-lg: "75em";
9 | $mantine-breakpoint-xl: "88em";
10 |
11 | @function rem($value) {
12 | @return #{math.div(math.div($value, $value * 0 + 1), 16)}rem;
13 | }
14 |
15 | @mixin light {
16 | [data-mantine-color-scheme="light"] & {
17 | @content;
18 | }
19 | }
20 |
21 | @mixin dark {
22 | [data-mantine-color-scheme="dark"] & {
23 | @content;
24 | }
25 | }
26 |
27 | @mixin hover {
28 | @media (hover: hover) {
29 | &:hover {
30 | @content;
31 | }
32 | }
33 |
34 | @media (hover: none) {
35 | &:active {
36 | @content;
37 | }
38 | }
39 | }
40 |
41 | @mixin smaller-than($breakpoint) {
42 | @media (max-width: $breakpoint) {
43 | @content;
44 | }
45 | }
46 |
47 | @mixin larger-than($breakpoint) {
48 | @media (min-width: $breakpoint) {
49 | @content;
50 | }
51 | }
52 |
53 | // Add direction mixins if you need rtl support
54 | @mixin rtl {
55 | [dir="rtl"] & {
56 | @content;
57 | }
58 | }
59 |
60 | @mixin ltr {
61 | [dir="ltr"] & {
62 | @content;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/_mantine.scss:
--------------------------------------------------------------------------------
1 | @use "sass:math";
2 |
3 | // Define variables for your breakpoints,
4 | // values must be the same as in your theme
5 | $mantine-breakpoint-xs: "36em";
6 | $mantine-breakpoint-sm: "48em";
7 | $mantine-breakpoint-md: "62em";
8 | $mantine-breakpoint-lg: "75em";
9 | $mantine-breakpoint-xl: "88em";
10 |
11 | @function rem($value) {
12 | @return #{math.div(math.div($value, $value * 0 + 1), 16)}rem;
13 | }
14 |
15 | @mixin light {
16 | [data-mantine-color-scheme="light"] & {
17 | @content;
18 | }
19 | }
20 |
21 | @mixin dark {
22 | [data-mantine-color-scheme="dark"] & {
23 | @content;
24 | }
25 | }
26 |
27 | @mixin hover {
28 | @media (hover: hover) {
29 | &:hover {
30 | @content;
31 | }
32 | }
33 |
34 | @media (hover: none) {
35 | &:active {
36 | @content;
37 | }
38 | }
39 | }
40 |
41 | @mixin smaller-than($breakpoint) {
42 | @media (max-width: $breakpoint) {
43 | @content;
44 | }
45 | }
46 |
47 | @mixin larger-than($breakpoint) {
48 | @media (min-width: $breakpoint) {
49 | @content;
50 | }
51 | }
52 |
53 | // Add direction mixins if you need rtl support
54 | @mixin rtl {
55 | [dir="rtl"] & {
56 | @content;
57 | }
58 | }
59 |
60 | @mixin ltr {
61 | [dir="ltr"] & {
62 | @content;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/pin-input-demo.tsx:
--------------------------------------------------------------------------------
1 | import { PinInput, PinInputProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { PinInput } from '@mantine/core';
6 |
7 | function Demo() {
8 | return
9 | }
10 | `;
11 |
12 | function Wrapper(props: PinInputProps) {
13 | return ;
14 | }
15 |
16 | export const pinInputDemo: MantineDemo = {
17 | type: 'configurator',
18 | component: Wrapper,
19 | code,
20 | centered: true,
21 | controls: [
22 | { prop: 'size', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
23 | { prop: 'length', type: 'number', initialValue: 4, libraryValue: 4, min: 1, max: 5 },
24 | { prop: 'mask', type: 'boolean', initialValue: false, libraryValue: false },
25 | { prop: 'placeholder', type: 'string', initialValue: '○', libraryValue: '○' },
26 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
27 | { prop: 'error', type: 'boolean', initialValue: false, libraryValue: false },
28 | {
29 | prop: 'type',
30 | type: 'select',
31 | initialValue: 'alphanumeric',
32 | libraryValue: 'alphanumeric',
33 | data: ['alphanumeric', 'number'],
34 | },
35 | ],
36 | };
37 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/CodeDemo/CodeDemo.tsx:
--------------------------------------------------------------------------------
1 | import { DemoArea, DemoAreaProps } from "../DemoArea";
2 | import { DemoCode, DemoCodeProps } from "../DemoCode";
3 | import { DemoRoot } from "../DemoRoot";
4 | import { useState } from "react";
5 | import { Button, Flex } from "@mantine/core";
6 |
7 | export interface CodeDemoProps extends DemoCodeProps, DemoAreaProps {}
8 |
9 | export function CodeDemo({
10 | code,
11 | children,
12 | withPadding,
13 | centered,
14 | defaultExpanded = true,
15 | maxWidth,
16 | minHeight,
17 | dimmed,
18 | striped,
19 | }: CodeDemoProps) {
20 | const [showCode, setShowCode] = useState(false);
21 |
22 | return (
23 |
24 |
32 | {children}
33 |
34 |
35 |
36 |
39 |
40 |
41 | {showCode && }
42 |
43 | );
44 | }
45 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/ConfiguratorSegmented.control.tsx:
--------------------------------------------------------------------------------
1 | import { BoxProps, ElementProps, Input, SegmentedControl } from '@mantine/core';
2 | import { getControlLabel } from './get-control-label';
3 | import { SelectData, transformSelectData } from './transform-select-data';
4 | import { ConfiguratorControl } from './types';
5 |
6 | export type ConfiguratorSegmentedControlOptions = ConfiguratorControl<
7 | 'segmented',
8 | { data: SelectData; initialValue: string }
9 | >;
10 |
11 | export interface ConfiguratorSegmentedControlProps
12 | extends BoxProps,
13 | ElementProps<'div', 'onChange'> {
14 | data: SelectData;
15 | value: string;
16 | onChange: (value: string) => void;
17 | prop: string;
18 | transformLabel?: boolean;
19 | }
20 |
21 | export function ConfiguratorSegmentedControl({
22 | data,
23 | value,
24 | onChange,
25 | prop,
26 | transformLabel = true,
27 | ...others
28 | }: ConfiguratorSegmentedControlProps) {
29 | return (
30 |
31 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/chip-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Chip, ChipProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: ChipProps) {
5 | return (
6 |
7 | Awesome chip
8 |
9 | );
10 | }
11 |
12 | const code = `
13 | import { Chip } from '@mantine/core';
14 |
15 | function Demo() {
16 | return Awesome chip
17 | }
18 | `;
19 |
20 | export const chipDemo: MantineDemo = {
21 | type: 'configurator',
22 | component: Wrapper,
23 | code,
24 | centered: true,
25 | controls: [
26 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
27 | {
28 | prop: 'variant',
29 | type: 'segmented',
30 | data: [
31 | { value: 'filled', label: 'Filled' },
32 | { value: 'outline', label: 'Outline' },
33 | { value: 'light', label: 'Light' },
34 | ],
35 | initialValue: '',
36 | libraryValue: '',
37 | },
38 | { prop: 'size', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
39 | { prop: 'radius', type: 'size', initialValue: 'xl', libraryValue: 'xl' },
40 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
41 | { prop: 'checked', type: 'boolean', initialValue: true, libraryValue: false },
42 |
43 | ],
44 | };
45 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/fieldset-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Fieldset, TextInput } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Fieldset, TextInput } from '@mantine/core';
6 |
7 | function Demo() {
8 | return (
9 |
13 | );
14 | }
15 | `;
16 |
17 | function Wrapper(props: any) {
18 | return (
19 |
23 | );
24 | }
25 |
26 | export const fieldsetDemo: MantineDemo = {
27 | type: 'configurator',
28 | component: Wrapper,
29 | code,
30 | maxWidth: 500,
31 | centered: true,
32 | controls: [
33 | {
34 | type: 'segmented',
35 | prop: 'variant',
36 | initialValue: '',
37 | libraryValue: '',
38 | data: ['default', 'filled', 'unstyled'],
39 | },
40 |
41 | { type: 'size', prop: 'radius', initialValue: 'sm', libraryValue: 'sm' },
42 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
43 | ],
44 | };
45 |
--------------------------------------------------------------------------------
/src/components/ui/header/header.module.scss:
--------------------------------------------------------------------------------
1 | .header {
2 | height: mantine.rem(56px);
3 | background-color: var(--mantine-color-body);
4 | padding-right: var(--mantine-spacing-3xl);
5 | padding-left: var(--mantine-spacing-3xl);
6 | position: sticky;
7 | top: 0;
8 | z-index: 100;
9 |
10 | mantine.mobile {
11 | padding-right: var(--mantine-spacing-md);
12 | padding-left: var(--mantine-spacing-md);
13 | }
14 | }
15 |
16 | .inner {
17 | height: mantine.rem(56px);
18 | display: flex;
19 | justify-content: space-between;
20 | align-items: center;
21 | }
22 |
23 | .link {
24 | display: block;
25 | line-height: 1;
26 | padding: mantine.rem(8px) mantine.rem(12px);
27 | border-radius: var(--mantine-radius-sm);
28 | text-decoration: none;
29 | color: rgb(from var(--mantine-color-text) r g b/0.6);
30 | font-size: var(--mantine-font-size-sm);
31 | font-weight: 500;
32 | cursor: pointer;
33 |
34 | @mixin hover {
35 | color: var(--mantine-color-default-hover);
36 | }
37 | }
38 |
39 | .tab {
40 | position: relative;
41 | border-top: 1px solid var(--mantine-color-default-border);
42 | background-color: var(--mantine-color-body);
43 |
44 |
45 | @mixin hover {
46 | background-color: var(--mantine-color-default-hover);
47 | }
48 | }
--------------------------------------------------------------------------------
/src/components/custom/components-demo/feedback/skeleton-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Skeleton, SkeletonProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: Partial) {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 |
12 | );
13 | }
14 |
15 | const code = (props: any) => `
16 | import { Skeleton } from '@mantine/core';
17 |
18 | function Demo() {
19 | return (
20 | <>
21 |
22 |
23 |
24 |
27 | >
28 | );
29 | }
30 | `;
31 |
32 | export const skeletonDemo: MantineDemo = {
33 | type: 'configurator',
34 | component: Wrapper,
35 | code,
36 | controls: [{ prop: 'animate', type: 'boolean', initialValue: true, libraryValue: '__' }],
37 | };
38 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/meet-our-team-1/meet-our-team-1.module.css:
--------------------------------------------------------------------------------
1 | .teamMemberCard {
2 | transition: all 0.3s ease;
3 | background: linear-gradient(145deg, var(--mantine-body-color), var(--mantine-color-gray-2));
4 | border: 1px solid var(--mantine-color-default-border);
5 | }
6 |
7 | .teamMemberCard:hover {
8 | transform: translateY(-10px);
9 | box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
10 | }
11 |
12 | .memberAvatar {
13 | border: 4px solid #fff;
14 | box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
15 | }
16 |
17 | .memberName {
18 | color: var(--mantine-primary-color-5);
19 | font-weight: 700;
20 | letter-spacing: -0.5px;
21 | }
22 |
23 | .memberRole {
24 | text-transform: uppercase;
25 | font-size: 0.8rem;
26 | letter-spacing: 1px;
27 | }
28 |
29 | .memberBio {
30 | font-style: italic;
31 | text-align: center;
32 | }
33 |
34 | .socialIcons svg {
35 | color: light-dark(var(--mantine-primary-color-7), var(--mantine-primary-color-5));
36 | opacity: 0.7;
37 | }
38 |
39 | .socialIcons a {
40 | transition: color 0.3s ease;
41 | }
42 |
43 | .socialIcons a:hover svg {
44 | opacity: 1;
45 | }
46 |
47 | .sectionTitle {
48 | background: linear-gradient(180deg, var(--mantine-primary-color-filled), var(--mantine-primary-color-8));
49 | -webkit-background-clip: text;
50 | -webkit-text-fill-color: transparent;
51 | font-weight: 900;
52 | text-align: center;
53 | }
54 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/miscellaneous/paper-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Paper, Text } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: any) {
5 | return (
6 |
7 |
8 | Paper is the most basic ui component
9 |
10 | Use it to create cards, dropdowns, modals and other components that require background
11 | with shadow
12 |
13 |
14 |
15 | );
16 | }
17 |
18 | const code = `
19 | import { Text, Paper } from '@mantine/core';
20 |
21 | function Demo() {
22 | return (
23 |
24 | Paper is the most basic ui component
25 |
26 | Use it to create cards, dropdowns, modals and other components that require background
27 | with shadow
28 |
29 |
30 | );
31 | }
32 | `;
33 |
34 | export const paperDemo: MantineDemo = {
35 | type: 'configurator',
36 | component: Wrapper,
37 | code,
38 | dimmed: true,
39 | controls: [
40 | { prop: 'shadow', type: 'size', initialValue: 'xs', libraryValue: 'none' },
41 | { prop: 'radius', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
42 | { prop: 'withBorder', type: 'boolean', initialValue: false, libraryValue: false },
43 | ],
44 | };
45 |
--------------------------------------------------------------------------------
/src/app/feedback/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { TestimonialGrid } from "@/components/custom/testimonial/testimonial-grid";
4 | import PageLayout from "@/components/layouts/page-layout";
5 | import { testimonialItems } from "@/utils/testimonials";
6 | import { Button, Group, Space, Stack } from "@mantine/core";
7 |
8 | export default function Page() {
9 | return (
10 |
15 |
16 |
17 |
26 |
35 |
36 |
37 |
38 |
39 |
40 | );
41 | }
42 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/buttons/action-icon-demo.tsx:
--------------------------------------------------------------------------------
1 | import { ActionIcon } from '@mantine/core';
2 | import { IconAdjustments } from '@tabler/icons-react';
3 | import { interactiveVariantsControl } from '../../../../utils/variants-data';
4 | import { MantineDemo } from '../../../mantine/demo';
5 |
6 | const code = `
7 | import { ActionIcon } from '@mantine/core';
8 | import { IconAdjustments } from '@tabler/icons-react';
9 |
10 | function Demo() {
11 | return (
12 |
13 |
14 |
15 | );
16 | }
17 | `;
18 |
19 | function Wrapper(props: any) {
20 | return (
21 |
22 |
23 |
24 | );
25 | }
26 |
27 | export const actionIconDemo: MantineDemo = {
28 | type: 'configurator',
29 | component: Wrapper,
30 | code,
31 | centered: true,
32 | controls: [
33 | interactiveVariantsControl,
34 | { prop: 'color', type: 'color', initialValue: "", libraryValue: "" },
35 | { prop: 'size', type: 'size', initialValue: 'md', libraryValue: 'md' },
36 | { prop: 'radius', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
37 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
38 |
39 | ],
40 | };
41 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoColumns/DemoColumns.tsx:
--------------------------------------------------------------------------------
1 | import { Text } from '@mantine/core';
2 | import { DemoArea, DemoAreaProps } from '../DemoArea';
3 | import classes from './DemoColumns.module.css';
4 |
5 | export interface DemoColumnsProps extends DemoAreaProps {
6 | title?: React.ReactNode;
7 | description?: React.ReactNode;
8 | controls: React.ReactNode;
9 | }
10 |
11 | export function DemoColumns({
12 | children,
13 | withPadding,
14 | centered,
15 | maxWidth,
16 | minHeight,
17 | title,
18 | description,
19 | controls,
20 | dimmed,
21 | striped,
22 | }: DemoColumnsProps) {
23 | return (
24 |
25 |
33 | {children}
34 |
35 |
36 |
37 | {title && (
38 |
39 |
40 | {title}
41 |
42 | {description && (
43 |
44 | {description}
45 |
46 | )}
47 |
48 | )}
49 |
50 | {controls}
51 |
52 |
53 | );
54 | }
55 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/switch-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Switch } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Switch } from '@mantine/core';
6 |
7 |
8 | function Demo() {
9 | return (
10 |
14 | );
15 | }
16 | `;
17 |
18 | export const switchDemo: MantineDemo = {
19 | type: 'configurator',
20 | component: (props: any) => ,
21 | code,
22 | centered: true,
23 | controls: [
24 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
25 | {
26 | prop: 'labelPosition',
27 | type: 'segmented',
28 | data: [
29 | { value: 'right', label: 'Right' },
30 | { value: 'left', label: 'Left' },
31 | ],
32 | initialValue: 'right',
33 | libraryValue: 'right',
34 | },
35 | { prop: 'label', type: 'string', initialValue: 'I agree to sell my privacy', libraryValue: '' },
36 | { prop: 'description', type: 'string', initialValue: '', libraryValue: '' },
37 | { prop: 'error', type: 'string', initialValue: '', libraryValue: '' },
38 | { prop: 'size', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
39 | { prop: 'radius', type: 'size', initialValue: 'xl', libraryValue: 'xl' },
40 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
41 | ],
42 | };
43 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/typography/blockquote-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Blockquote } from '@mantine/core';
2 | import { IconInfoCircle } from '@tabler/icons-react';
3 | import { MantineDemo } from '../../../mantine/demo';
4 |
5 | const code = `
6 | import { Blockquote } from '@mantine/core';
7 | import { IconInfoCircle } from '@tabler/icons-react';
8 |
9 | function Demo() {
10 | const icon = ;
11 | return (
12 |
13 | Life is like an npm install – you never know what you are going to get.
14 |
15 | );
16 | }
17 | `;
18 |
19 | function Wrapper(props: any) {
20 | const icon = ;
21 | return (
22 |
23 | Life is like an npm install – you never know what you are going to get.
24 |
25 | );
26 | }
27 |
28 | export const blockquoteDemo: MantineDemo = {
29 | type: 'configurator',
30 | component: Wrapper,
31 | code,
32 | centered: true,
33 | maxWidth: 380,
34 | controls: [
35 | { type: 'color', prop: 'color', initialValue: '', libraryValue: '' },
36 | { type: 'size', prop: 'radius', initialValue: 'sm', libraryValue: 'sm' },
37 | {
38 | type: 'number',
39 | prop: 'iconSize',
40 | initialValue: 48,
41 | min: 30,
42 | max: 60,
43 | step: 1,
44 | libraryValue: 48,
45 | },
46 | ],
47 | };
48 |
--------------------------------------------------------------------------------
/src/app/about/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { AboutPage } from "@/components/custom/about/about";
4 | import PageLayout from "@/components/layouts/page-layout";
5 | import { Box, Button, Group, Space, Stack } from "@mantine/core";
6 |
7 | export default function Page() {
8 | return (
9 |
14 |
15 |
16 |
25 |
34 |
35 |
36 |
41 |
42 |
43 |
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/src/components/custom/theme-example-cards/create-account.tsx:
--------------------------------------------------------------------------------
1 |
2 | import { Button, Card, TextInput, Divider, Text, Group, Title } from '@mantine/core';
3 | import { Icons } from '../../ui/icons';
4 |
5 | export function CardsCreateAccount() {
6 | return (
7 |
8 |
9 | Create an account
10 |
11 | Enter your email below to create your account
12 |
13 |
14 |
15 |
16 | }>
17 | GitHub
18 |
19 | }>
20 | Google
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | );
34 | }
35 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/components-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Divider, Group, Stack, Title } from "@mantine/core";
2 | import { demoComponentsNavbarData } from "../../../utils/data";
3 | import { Demo } from "../../mantine/demo";
4 | import Navbar from "../../ui/navbar/navbar";
5 | import classes from "./components-demo.module.css";
6 |
7 | const ComponentsDemo = () => {
8 |
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | {demoComponentsNavbarData?.map((item) => {
18 | return (
19 |
20 | {item.label}
21 |
22 | {item.links.map((link) => {
23 | return (
24 |
25 |
26 | {link.label}
27 |
28 | {link.demo && }
29 |
30 | );
31 | })}
32 |
33 | );
34 | })}
35 |
36 |
37 | );
38 | };
39 |
40 | export default ComponentsDemo;
41 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/slider-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Slider } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: any) {
5 | return (
6 |
16 | );
17 | }
18 |
19 | const code = `
20 | import { Slider } from '@mantine/core';
21 |
22 |
23 | function Demo() {
24 | return (
25 |
33 | );
34 | }
35 | `;
36 |
37 | export const sliderDemo: MantineDemo = {
38 | type: 'configurator',
39 | component: Wrapper,
40 | code,
41 | centered: true,
42 | maxWidth: 400,
43 | controls: [
44 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '__none__' },
45 | { prop: 'size', type: 'size', initialValue: 'md', libraryValue: 'md' },
46 | { prop: 'radius', type: 'size', initialValue: 'xl', libraryValue: 'xl' },
47 | { prop: 'showLabelOnHover', type: 'boolean', initialValue: true, libraryValue: true },
48 | { prop: 'labelAlwaysOn', type: 'boolean', initialValue: false, libraryValue: false },
49 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
50 | ],
51 | };
52 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/ConfiguratorSize.control.tsx:
--------------------------------------------------------------------------------
1 | import { BoxProps, ElementProps, Input, Slider } from '@mantine/core';
2 | import { getControlLabel } from './get-control-label';
3 | import { ConfiguratorControl } from './types';
4 |
5 | const MARKS = [
6 | { value: 0, label: 'xs' },
7 | { value: 25, label: 'sm' },
8 | { value: 50, label: 'md' },
9 | { value: 75, label: 'lg' },
10 | { value: 100, label: 'xl' },
11 | ];
12 |
13 | export type ConfiguratorSizeControlOptions = ConfiguratorControl<'size', { initialValue: string }>;
14 |
15 | export interface ConfiguratorSizeControlProps extends BoxProps, ElementProps<'div', 'onChange'> {
16 | value: string;
17 | onChange: (value: string) => void;
18 | prop: string;
19 | }
20 |
21 | export function ConfiguratorSizeControl({
22 | value,
23 | onChange,
24 | prop,
25 | ...others
26 | }: ConfiguratorSizeControlProps) {
27 | const _value = MARKS.find((mark) => mark.label === value)!.value;
28 | const handleChange = (val: number) => onChange(MARKS.find((mark) => mark.value === val)!.label);
29 |
30 | return (
31 |
32 | MARKS.find((mark) => mark.value === val)!.label}
36 | step={25}
37 | marks={MARKS}
38 | styles={{ markLabel: { display: 'none' } }}
39 | thumbLabel="Size"
40 | />
41 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/overlays/hover-card-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Group, HoverCard, Text } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { HoverCard, Button, Text, Group } from '@mantine/core';
6 |
7 | function Demo() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Hover card is revealed when user hovers over target element, it will be hidden once
17 | mouse is not over both target and dropdown elements
18 |
19 |
20 |
21 |
22 | );
23 | }
24 |
25 | `;
26 |
27 | function Demo() {
28 | return (
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | Hover card is revealed when user hovers over target element, it will be hidden once
37 | mouse is not over both target and dropdown elements
38 |
39 |
40 |
41 |
42 | );
43 | }
44 |
45 | export const hoverCardDemo: MantineDemo = {
46 | type: 'code',
47 | component: Demo,
48 | code,
49 | };
50 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/feedback/notification-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Notification, NotificationProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: NotificationProps) {
5 | return (
6 |
7 | {}} {...props} />
8 |
9 | );
10 | }
11 |
12 | const code = `
13 | import { Notification } from '@mantine/core';
14 |
15 | function Demo() {
16 | return (
17 |
18 | {{children}}
19 |
20 | );
21 | }
22 | `;
23 |
24 | export const notificationDemo: MantineDemo = {
25 | type: 'configurator',
26 | component: Wrapper,
27 | centered: true,
28 | code,
29 | // dimmed: true,
30 | controls: [
31 | { prop: 'loading', type: 'boolean', initialValue: false, libraryValue: false },
32 | { prop: 'withCloseButton', type: 'boolean', initialValue: true, libraryValue: true },
33 | { prop: 'withBorder', type: 'boolean', initialValue: false, libraryValue: false },
34 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
35 | { prop: 'radius', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
36 | {
37 | prop: 'title',
38 | type: 'string',
39 | initialValue: 'We notify you that',
40 | libraryValue: '',
41 | },
42 | {
43 | prop: 'children',
44 | type: 'string',
45 | initialValue: 'You are now obligated to give a star to Mantine project on GitHub',
46 | libraryValue: '',
47 | },
48 | ],
49 | };
50 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/feedback/alert-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Alert } from '@mantine/core';
2 | import { IconInfoCircle } from '@tabler/icons-react';
3 | import { staticVariantsControl } from '../../../../utils/variants-data';
4 | import { MantineDemo } from '../../../mantine/demo';
5 |
6 | const code = `
7 | import { Alert } from '@mantine/core';
8 | import { IconInfoCircle } from '@tabler/icons-react';
9 |
10 | function Demo() {
11 | const icon = ;
12 | return (
13 |
14 | {{children}}
15 |
16 | );
17 | }
18 | `;
19 |
20 | function Wrapper(props: any) {
21 | return } {...props} />;
22 | }
23 |
24 | export const alertDemo: MantineDemo = {
25 | type: 'configurator',
26 | component: Wrapper,
27 | code,
28 | centered: true,
29 | maxWidth: 400,
30 | controls: [
31 | { ...(staticVariantsControl as any), initialValue: 'light', libraryValue: 'light' },
32 | { type: 'color', prop: 'color', initialValue: '', libraryValue: '' },
33 | { type: 'size', prop: 'radius', initialValue: 'sm', libraryValue: 'sm' },
34 | { type: 'boolean', prop: 'withCloseButton', initialValue: false, libraryValue: false },
35 | { type: 'string', prop: 'title', initialValue: 'Alert title', libraryValue: null },
36 | {
37 | type: 'string',
38 | prop: 'children',
39 | initialValue:
40 | 'Lorem ipsum dolor sit, amet consectetur adipisicing elit. At officiis, quae tempore necessitatibus placeat saepe.',
41 | libraryValue: null,
42 | },
43 | ],
44 | };
45 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/overlays/loading-overlay-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Button, Group, LoadingOverlay } from '@mantine/core';
2 | import { useDisclosure } from '@mantine/hooks';
3 | import { AuthenticationForm } from './authentication-form';
4 | import { MantineDemo } from '../../../mantine/demo';
5 |
6 | const code = `
7 | import { useDisclosure } from '@mantine/hooks';
8 | import { LoadingOverlay, Button, Group, Box } from '@mantine/core';
9 |
10 | function Demo() {
11 | const [visible, { toggle }] = useDisclosure(false);
12 |
13 | // Note that position: relative is required
14 | return (
15 | <>
16 |
17 |
18 | {/* ...other content */}
19 |
20 |
21 |
22 |
23 |
24 | >
25 | );
26 | }`;
27 |
28 | export function Demo() {
29 | const [visible, { toggle }] = useDisclosure(false);
30 | return (
31 | <>
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | >
41 | );
42 | }
43 |
44 | export const loadingOverlayDemo: MantineDemo = {
45 | centered: true,
46 | maxWidth: 400,
47 | dimmed: true,
48 | type: 'code',
49 | code,
50 | component: Demo,
51 | };
52 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/segmented-control-demo.tsx:
--------------------------------------------------------------------------------
1 | import { SegmentedControl } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { SegmentedControl } from '@mantine/core';
6 |
7 | function Demo() {
8 | return ;
9 | }
10 | `;
11 |
12 | function Wrapper(props: any) {
13 | return ;
14 | }
15 |
16 | export const segmentedControlDemo: MantineDemo = {
17 | type: 'configurator',
18 | component: Wrapper,
19 | code,
20 | controls: [
21 | {
22 | prop: 'orientation',
23 | type: 'segmented',
24 | initialValue: 'horizontal',
25 | libraryValue: 'horizontal',
26 | data: [
27 | { label: 'horizontal', value: 'horizontal' },
28 | { label: 'vertical', value: 'vertical' },
29 | ],
30 | },
31 | { prop: 'fullWidth', type: 'boolean', initialValue: false, libraryValue: false },
32 | { prop: 'withItemsBorders', type: 'boolean', initialValue: true, libraryValue: true },
33 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
34 | { type: 'size', prop: 'size', initialValue: 'sm', libraryValue: 'sm' },
35 | { type: 'size', prop: 'radius', initialValue: 'sm', libraryValue: 'sm' },
36 | { prop: 'transitionDuration', type: 'string', initialValue: '150', libraryValue: '150' },
37 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
38 | { prop: 'readOnly', type: 'boolean', initialValue: false, libraryValue: false },
39 | ],
40 | };
41 |
--------------------------------------------------------------------------------
/src/components/custom/testimonial/testimonial-item.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Text, Group, Stack, Avatar, UnstyledButton } from "@mantine/core";
2 |
3 | export interface ITestimonialItem {
4 | className?: string;
5 | url?: string;
6 | text: string;
7 | imageSrc: string;
8 | name: string;
9 | handle: string;
10 | }
11 |
12 | export const TestimonialItem = ({ url, text, imageSrc, name, handle }: ITestimonialItem) => {
13 | const missingUrl = !url || url === "#";
14 | return (
15 |
26 |
27 |
28 |
29 | "{text}"
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | {name}
38 |
39 | {handle}
40 |
41 |
42 |
43 |
44 |
45 |
46 | );
47 | };
48 |
--------------------------------------------------------------------------------
/src/components/ui/navbar/navbar.module.scss:
--------------------------------------------------------------------------------
1 |
2 | .navbar {
3 | width: mantine.rem(290px);
4 | padding: var(--mantine-spacing-2xs);
5 | border: 1px solid var(--mantine-color-default-border);
6 | border-radius: var(--mantine-radius-default);
7 | }
8 |
9 | .control {
10 | display: block;
11 | width: 100%;
12 | padding-left: var(--mantine-spacing-sm) !important;
13 | padding-right: var(--mantine-spacing-sm) !important;
14 | color: var(--mantine-color-text) !important;
15 | font-size: var(--mantine-font-size-sm) !important;
16 | border-radius: var(--mantine-radius-default);
17 | &:hover {
18 | background-color: var(--mantine-color-default-hover);
19 | }
20 | }
21 |
22 | .linkGroup {
23 | border-left: 1px solid var(--mantine-color-secondary-outline);
24 | margin-left: var(--mantine-spacing-lg);
25 | padding-left: var(--mantine-spacing-sm);
26 | display: flex;
27 | flex-direction: column;
28 | gap: var(--mantine-spacing-4xs);
29 | }
30 |
31 | .link {
32 | display: block;
33 | text-decoration: none;
34 | padding-left: var(--mantine-spacing-sm) !important;
35 | padding-right: var(--mantine-spacing-sm) !important;
36 | font-size: var(--mantine-font-size-sm) !important;
37 | color: var(--mantine-color-text) !important;
38 | border-radius: var(--mantine-radius-default) !important;
39 | height: 2.25rem;
40 | display: flex;
41 | align-items: center;
42 | cursor: pointer;
43 |
44 | &:hover {
45 | background-color: var(--mantine-color-default-hover);
46 | }
47 | }
48 |
49 | .chevron {
50 | transition: transform 200ms ease;
51 | }
--------------------------------------------------------------------------------
/src/components/mantine/demo/DemoArea/DemoArea.module.css:
--------------------------------------------------------------------------------
1 | .demo {
2 | flex: 1;
3 | border-top-left-radius: calc(var(--mantine-radius-md) - 1px);
4 | border-top-right-radius: calc(var(--mantine-radius-md) - 1px);
5 |
6 | &:where([data-with-padding]) {
7 | padding: var(--mantine-spacing-md);
8 | }
9 |
10 | &[data-dimmed] {
11 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-8));
12 | }
13 |
14 | &[data-centered] {
15 | display: flex;
16 | justify-content: center;
17 | align-items: center;
18 | }
19 |
20 | &[data-striped] {
21 | border-top-left-radius: calc(var(--mantine-radius-md) - 1px);
22 | background: repeating-linear-gradient(
23 | 45deg,
24 | transparent 0,
25 | transparent 10px,
26 | var(--stripe-color) 10px,
27 | var(--stripe-color) 12px
28 | ),
29 | repeating-linear-gradient(
30 | 135deg,
31 | transparent 0,
32 | transparent 10px,
33 | var(--stripe-color) 10px,
34 | var(--stripe-color) 12px
35 | );
36 |
37 | @mixin rtl {
38 | border-top-right-radius: calc(var(--mantine-radius-md) - 1px);
39 | border-top-left-radius: 0;
40 | }
41 |
42 | @mixin light {
43 | --stripe-color: rgba(0, 0, 0, 0.03);
44 | }
45 |
46 | @mixin dark {
47 | --stripe-color: rgba(255, 255, 255, 0.03);
48 | }
49 | }
50 | }
51 |
52 | .demoInner {
53 | flex: var(--demo-flex);
54 | max-width: var(--demo-max-width, 100%);
55 | min-height: var(--demo-min-height, unset);
56 | margin-left: var(--demo-margin-y, unset);
57 | margin-right: var(--demo-margin-y, unset);
58 | }
59 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/feedback/semi-circle-progress-demo.tsx:
--------------------------------------------------------------------------------
1 | import { SemiCircleProgress } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { SemiCircleProgress } from '@mantine/core';
6 |
7 |
8 | function Demo() {
9 | return (
10 |
14 | );
15 | }
16 | `;
17 |
18 | function Wrapper(props: any) {
19 | return ;
20 | }
21 |
22 | export const semiCircleProgressDemo: MantineDemo = {
23 | type: 'configurator',
24 | component: Wrapper,
25 | code,
26 | centered: true,
27 | controls: [
28 | {
29 | type: 'segmented',
30 | prop: 'fillDirection',
31 | initialValue: 'left-to-right',
32 | data: [
33 | { label: 'Right to left', value: 'right-to-left' },
34 | { label: 'Left to right', value: 'left-to-right' },
35 | ],
36 | libraryValue: null,
37 | },
38 | {
39 | type: 'segmented',
40 | prop: 'orientation',
41 | initialValue: 'up',
42 | data: [
43 | { label: 'Up', value: 'up' },
44 | { label: 'Down', value: 'down' },
45 | ],
46 | libraryValue: null,
47 | },
48 | { type: 'color', prop: 'filledSegmentColor', initialValue: '', libraryValue: '' },
49 | { type: 'number', prop: 'size', min: 120, max: 450, initialValue: 200, libraryValue: null },
50 | { type: 'number', prop: 'thickness', min: 1, max: 20, initialValue: 12, libraryValue: null },
51 | { type: 'number', prop: 'value', min: 0, max: 100, initialValue: 40, libraryValue: null },
52 | ],
53 | };
54 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/radar-chart-demo.tsx:
--------------------------------------------------------------------------------
1 | import { RadarChart } from '@mantine/charts';
2 | import { multiData, multiDataCode } from './data/_radar-data';
3 | import { MantineDemo } from '../../../mantine/demo';
4 |
5 | const code = `
6 | import { RadarChart } from '@mantine/charts';
7 | import { data } from './data';
8 |
9 |
10 | function Demo() {
11 | return (
12 |
22 | );
23 | }
24 | `;
25 |
26 | function Demo(props: any) {
27 | return (
28 |
39 | );
40 | }
41 |
42 | export const radarChartDemo: MantineDemo = {
43 | type: 'configurator',
44 | component: Demo,
45 | code: [
46 | { code, language: 'tsx', fileName: 'Demo.tsx' },
47 | { code: multiDataCode, language: 'tsx', fileName: 'data.ts' },
48 | ],
49 | controls: [
50 | { type: 'boolean', prop: 'withPolarGrid', initialValue: true, libraryValue: null },
51 | { type: 'boolean', prop: 'withPolarAngleAxis', initialValue: true, libraryValue: null },
52 | { type: 'boolean', prop: 'withPolarRadiusAxis', initialValue: true, libraryValue: null },
53 | ],
54 | };
55 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/overlays/overlay-demo.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react';
2 | import { AspectRatio, Button, Overlay } from '@mantine/core';
3 | import { MantineDemo } from '../../../mantine/demo';
4 |
5 | const code = `
6 | import { useState } from 'react';
7 | import { Button, Overlay, AspectRatio } from '@mantine/core';
8 |
9 | function Demo() {
10 | const [visible, setVisible] = useState(true);
11 | return (
12 | <>
13 |
14 |
18 | {visible && }
19 |
20 |
23 | >
24 | );
25 | }
26 | `;
27 |
28 | function Demo() {
29 | const [visible, setVisible] = useState(true);
30 | return (
31 | <>
32 |
33 |
37 | {visible && }
38 |
39 |
42 | >
43 | );
44 | }
45 |
46 | export const overlayDemo: MantineDemo = {
47 | type: 'code',
48 | code,
49 | component: Demo,
50 | };
51 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/data-display/theme-icon-demo.tsx:
--------------------------------------------------------------------------------
1 | import { ThemeIcon, ThemeIconProps } from '@mantine/core';
2 | import { IconPhoto } from '@tabler/icons-react';
3 | import { MantineDemo } from '../../../mantine/demo';
4 |
5 | function Wrapper(props: ThemeIconProps) {
6 | return (
7 |
8 |
9 |
10 |
11 |
12 | );
13 | }
14 |
15 | const code = `
16 | import { ThemeIcon } from '@mantine/core';
17 | import { IconPhoto } from '@tabler/icons-react';
18 |
19 | function Demo() {
20 | return (
21 |
22 |
23 |
24 | );
25 | }
26 | `;
27 |
28 | export const themeIconDemo: MantineDemo = {
29 | type: 'configurator',
30 | component: Wrapper,
31 | code,
32 | centered: true,
33 | controls: [
34 | {
35 | prop: 'variant',
36 | type: 'select',
37 | initialValue: 'filled',
38 | libraryValue: 'filled',
39 | data: [
40 | { label: 'filled', value: 'filled' },
41 | { label: 'light', value: 'light' },
42 | { label: 'outline', value: 'outline' },
43 | { label: 'default', value: 'default' },
44 | { label: 'white', value: 'white' },
45 | ],
46 | },
47 | { prop: 'radius', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
48 | { prop: 'size', type: 'size', initialValue: 'md', libraryValue: 'md' },
49 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
50 | ],
51 | };
52 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/data-display/background-image-demo.tsx:
--------------------------------------------------------------------------------
1 | import { BackgroundImage, BackgroundImageProps, Box, Center, Text } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: BackgroundImageProps) {
5 | return (
6 |
7 |
11 |
12 |
13 | BackgroundImage component can be used to add any content on image. It is useful for hero
14 | headers and other similar sections
15 |
16 |
17 |
18 |
19 | );
20 | }
21 |
22 | const code = `
23 | import { BackgroundImage, Center, Text, Box } from '@mantine/core';
24 |
25 |
26 | function Demo() {
27 | return (
28 |
29 |
33 |
34 |
35 | BackgroundImage component can be used to add any content on image. It is useful for hero
36 | headers and other similar sections
37 |
38 |
39 |
40 |
41 | );
42 | }
43 | `;
44 |
45 | export const backgroundImageDemo: MantineDemo = {
46 | type: 'configurator',
47 | component: Wrapper,
48 | code,
49 | controls: [{ prop: 'radius', type: 'size', initialValue: 'sm', libraryValue: null }],
50 | };
51 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/feature1/feature1.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | position: relative;
3 | }
4 |
5 | .title {
6 | position: relative;
7 | font-weight: 900;
8 | background: linear-gradient(180deg, var(--mantine-primary-color-filled), var(--mantine-primary-color-8));
9 | -webkit-background-clip: text;
10 | -webkit-text-fill-color: transparent;
11 | }
12 |
13 | .title::after {
14 | content: "";
15 | display: block;
16 | width: 60px;
17 | height: 4px;
18 | background: linear-gradient(45deg, var(--mantine-primary-color-5), var(--mantine-primary-color-2));
19 | margin: 20px auto;
20 | border-radius: var(--mantine-radius-xl);
21 | }
22 |
23 | .card {
24 | transition: all 0.1s ease;
25 | }
26 |
27 | .card:hover {
28 | transform: translateY(-5px);
29 | box-shadow: var(--mantine-shadow-lg);
30 | background: var(--mantine-color-secondary-filled);
31 | }
32 |
33 | .iconWrapper {
34 | width: 60px;
35 | height: 60px;
36 | border-radius: var(--mantine-radius-md);
37 | /* background: linear-gradient(45deg, var(--mantine-primary-color-6), var(--mantine-primary-color-5)); */
38 | background: var(--mantine-primary-color-filled-hover);
39 | color: var(--mantine-primary-color-contrast);
40 | animation: float 3s ease-in-out infinite;
41 | display: flex;
42 | align-items: center;
43 | justify-content: center;
44 | }
45 |
46 | .iconWrapper svg {
47 | width: 24px;
48 | height: 24px;
49 | }
50 |
51 | .cardTitle {
52 | font-size: 1.5rem;
53 | font-weight: 600;
54 | }
55 |
56 | @keyframes float {
57 | 0% {
58 | transform: translateY(0);
59 | }
60 | 50% {
61 | transform: translateY(-10px);
62 | }
63 | 100% {
64 | transform: translateY(0);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/switch-group-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Group, Switch, SwitchGroupProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Switch, Group } from '@mantine/core';
6 |
7 | function Demo() {
8 | return (
9 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | );
21 | }
22 | `;
23 |
24 | function Wrapper(props: SwitchGroupProps) {
25 | return (
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | );
35 | }
36 |
37 | export const switchGroupDemo: MantineDemo = {
38 | type: 'configurator',
39 | component: Wrapper,
40 | code,
41 | centered: true,
42 | controls: [
43 | {
44 | prop: 'label',
45 | type: 'string',
46 | initialValue: 'Select your favorite framework/library',
47 | libraryValue: '',
48 | },
49 | { prop: 'description', type: 'string', initialValue: 'This is anonymous', libraryValue: '' },
50 | { prop: 'error', type: 'string', initialValue: '', libraryValue: '' },
51 | { prop: 'withAsterisk', type: 'boolean', initialValue: true, libraryValue: false },
52 | ],
53 | };
54 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/get-code-array.ts:
--------------------------------------------------------------------------------
1 |
2 | import { clearProps } from './clear-props';
3 | import type { ConfiguratorControlOptions } from './ConfiguratorDemo';
4 | import { ShikiLanguage } from './controls/types';
5 | import { injectProps } from './inject-props';
6 |
7 | type CodePayload = string | ((props: Record) => string);
8 |
9 |
10 | export type Code = CodePayload | { code: CodePayload; language: ShikiLanguage; fileName: string }[];
11 |
12 | interface GetCodeArrayInput {
13 | code: Code;
14 | controls: ConfiguratorControlOptions[];
15 | state: Record;
16 | }
17 |
18 | interface TransformCodePayloadInput {
19 | code: CodePayload;
20 | controls: ConfiguratorControlOptions[];
21 | state: Record;
22 | }
23 |
24 | function transformCodePayload({ code, controls, state }: TransformCodePayloadInput) {
25 | return typeof code === 'function'
26 | ? code(clearProps(controls, state))
27 | : injectProps(clearProps(controls, state), code);
28 | }
29 |
30 | export function getCodeArray({ code, controls, state }: GetCodeArrayInput) {
31 | if (typeof code === 'string' || typeof code === 'function') {
32 | return [
33 | {
34 | fileName: 'Demo.tsx',
35 | language: 'tsx' as const,
36 | code: transformCodePayload({ code, controls, state }),
37 | },
38 | ];
39 | }
40 |
41 | if (Array.isArray(code)) {
42 | return code.map((item) => ({
43 | fileName: item.fileName || 'Demo.tsx',
44 | language: item.language || 'tsx',
45 | code: transformCodePayload({ code: item.code, controls, state }),
46 | }));
47 | }
48 |
49 | throw new Error('Unexpected code format in configurator');
50 | }
51 |
--------------------------------------------------------------------------------
/src/styles/fonts.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Geist';
3 | src: url('./../assets/fonts/Geist-Thin.woff2') format('woff2');
4 | font-weight: 100;
5 | font-style: normal;
6 | }
7 |
8 | @font-face {
9 | font-family: 'Geist';
10 | src: url('./../assets/fonts/Geist-ExtraLight.woff2') format('woff2');
11 | font-weight: 200;
12 | font-style: normal;
13 | }
14 |
15 | @font-face {
16 | font-family: 'Geist';
17 | src: url('./../assets/fonts/Geist-Light.woff2') format('woff2');
18 | font-weight: 300;
19 | font-style: normal;
20 | }
21 |
22 | @font-face {
23 | font-family: 'Geist';
24 | src: url('./../assets/fonts/Geist-Regular.woff2') format('woff2');
25 | font-weight: 400;
26 | font-style: normal;
27 | }
28 |
29 | @font-face {
30 | font-family: 'Geist';
31 | src: url('./../assets/fonts/Geist-Medium.woff2') format('woff2');
32 | font-weight: 500;
33 | font-style: normal;
34 | }
35 |
36 | @font-face {
37 | font-family: 'Geist';
38 | src: url('./../assets/fonts/Geist-SemiBold.woff2') format('woff2');
39 | font-weight: 600;
40 | font-style: normal;
41 | }
42 |
43 | @font-face {
44 | font-family: 'Geist';
45 | src: url('./../assets/fonts/Geist-Bold.woff2') format('woff2');
46 | font-weight: 700;
47 | font-style: normal;
48 | }
49 |
50 | @font-face {
51 | font-family: 'Geist';
52 | src: url('./../assets/fonts/Geist-ExtraBold.woff2') format('woff2');
53 | font-weight: 800;
54 | font-style: normal;
55 | }
56 |
57 | @font-face {
58 | font-family: 'Geist';
59 | src: url('./../assets/fonts/Geist-Black.woff2') format('woff2');
60 | font-weight: 900;
61 | font-style: normal;
62 | }
63 |
64 |
65 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/radio-group-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Group, Radio, RadioGroupProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Radio, Group } from '@mantine/core';
6 |
7 |
8 | function Demo() {
9 | return (
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | );
22 | }
23 | `;
24 |
25 | function Wrapper(props: Partial) {
26 | return (
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | );
36 | }
37 |
38 | export const radioGroupDemo: MantineDemo = {
39 | type: 'configurator',
40 | component: Wrapper,
41 | centered: true,
42 | code,
43 | controls: [
44 | {
45 | prop: 'label',
46 | type: 'string',
47 | initialValue: 'Select your favorite framework/library',
48 | libraryValue: '',
49 | },
50 | { prop: 'description', type: 'string', initialValue: 'This is anonymous', libraryValue: '' },
51 | { prop: 'error', type: 'string', initialValue: '', libraryValue: '' },
52 | { prop: 'withAsterisk', type: 'boolean', initialValue: true, libraryValue: false },
53 | ],
54 | };
55 |
--------------------------------------------------------------------------------
/src/components/custom/theme-example-cards/metric.tsx:
--------------------------------------------------------------------------------
1 | import { LineChart } from "@mantine/charts";
2 | import { alpha, Box, Card, Text, Title, useMantineTheme } from "@mantine/core";
3 | import { metricData } from "../../../utils/data";
4 | import { ChartTooltip } from "../../ui/chart-tooltip";
5 | // import { Line, LineChart, ResponsiveContainer, Tooltip } from "recharts";
6 |
7 | export function CardsMetric() {
8 | const theme = useMantineTheme();
9 |
10 | return (
11 |
12 |
13 | Exercise Minutes
14 |
15 | Your exercise minutes are ahead of where you normally are.
16 |
17 |
18 |
19 |
20 | ,
34 | }}
35 | dotProps={{ strokeWidth: 2, fill: "#fff" }}
36 | lineProps={(series) => ({
37 | dataKey: series.name,
38 | isAnimationActive: true,
39 | // opacity: series.name === "average" ? 0.25 : 1,
40 | })}
41 | />
42 |
43 |
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/js/scripts/compileTS.cjs:
--------------------------------------------------------------------------------
1 | const { exec } = require("child_process");
2 | const path = require("path");
3 | const fs = require("fs");
4 |
5 | // Function to convert .ts file to .js and save it in the current script directory
6 | function convertTsToJs(tsFilePath) {
7 | const outputDir = path.resolve(__dirname, "../generated"); // Set output directory as the current directory of this script
8 | const command = `tsc ${tsFilePath} --outDir ${outputDir} --allowJs --esModuleInterop`;
9 |
10 | exec(command, (error, stdout, stderr) => {
11 | if (error) {
12 | console.error(`Error converting file: ${tsFilePath}`);
13 | console.error(stderr);
14 | } else {
15 | const fileName = path.basename(tsFilePath, ".ts");
16 | const jsFilePath = path.join(outputDir, `${fileName}.js`);
17 | const cjsFilePath = path.join(outputDir, `${fileName}.cjs`);
18 |
19 | // Rename .js to .cjs
20 | if (fs.existsSync(jsFilePath)) {
21 | fs.renameSync(jsFilePath, cjsFilePath);
22 | console.log(`Successfully converted and saved as: ${cjsFilePath}`);
23 |
24 | // Fix imports in the .cjs file
25 | let fileContent = fs.readFileSync(cjsFilePath, "utf8");
26 | fileContent = fileContent.replace(/require\("\.\/(.*?)"\)/g, 'require("./$1.cjs")');
27 | fs.writeFileSync(cjsFilePath, fileContent, "utf8");
28 | console.log(`Fixed import paths in: ${cjsFilePath}`);
29 | } else {
30 | console.error(`Expected .js file not found at: ${jsFilePath}`);
31 | }
32 | }
33 | });
34 | }
35 |
36 | // Convert specific TypeScript files
37 | convertTsToJs(path.join(__dirname, "../../src/utils/colors.ts"));
38 | convertTsToJs(path.join(__dirname, "../../src/utils/theme-functions.ts"));
39 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/inject-props.tsx:
--------------------------------------------------------------------------------
1 | function isMultiLine(code: string) {
2 | const placeholderLine = code.split('\n').find((line) => line.includes('{{props}}'));
3 | return placeholderLine && placeholderLine.trim().startsWith('{{props}}');
4 | }
5 |
6 | export function injectProps(props: any, code: string) {
7 | const propStrings: string[] = [];
8 | const multiline = isMultiLine(code);
9 | const replacedChildrenCode = code.replace('{{children}}', props.children || '');
10 |
11 | for (const [key, value] of Object.entries(props)) {
12 | if (key !== 'children') {
13 | if (typeof value === 'string') {
14 | propStrings.push(`${key}="${value}"`);
15 | } else if (typeof value === 'number') {
16 | propStrings.push(`${key}={${value}}`);
17 | } else if (typeof value === 'boolean') {
18 | if (value) {
19 | propStrings.push(key);
20 | } else {
21 | propStrings.push(`${key}={false}`);
22 | }
23 | }
24 | }
25 | }
26 |
27 | if (!multiline) {
28 | const joined = propStrings.join(' ');
29 | return joined.length > 0
30 | ? replacedChildrenCode.replace('{{props}}', ` ${joined}`)
31 | : replacedChildrenCode.replace('{{props}}', '');
32 | }
33 |
34 | const placeholderRegex = /^(\s*){{props}}(\s*)$/gm;
35 |
36 | const result = replacedChildrenCode.replace(placeholderRegex, (_, before, after) => {
37 | const propsWithWhitespace = propStrings
38 | .map(
39 | (propString, index) =>
40 | `${before}${propString}${index !== propStrings.length - 1 ? '\n' : ''}`
41 | )
42 | .join('');
43 | return `${propsWithWhitespace}${after}`;
44 | });
45 |
46 | return result.trim().replace('\n\n', '\n');
47 | }
48 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/radio-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Radio, RadioProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Radio } from '@mantine/core';
6 |
7 |
8 | function Demo() {
9 | return (
10 |
13 | );
14 | }
15 | `;
16 |
17 | function Wrapper(props: RadioProps) {
18 | return (
19 |
20 |
21 |
22 | );
23 | }
24 |
25 | export const radioDemo: MantineDemo = {
26 | type: 'configurator',
27 | component: Wrapper,
28 | code,
29 | centered: true,
30 | controls: [
31 | {
32 | prop: 'labelPosition',
33 | type: 'segmented',
34 | data: [
35 | { value: 'right', label: 'Right' },
36 | { value: 'left', label: 'Left' },
37 | ],
38 | initialValue: 'right',
39 | libraryValue: 'right',
40 | },
41 | { prop: 'label', type: 'string', initialValue: 'I cannot be unchecked', libraryValue: '' },
42 | { prop: 'description', type: 'string', initialValue: '', libraryValue: '' },
43 | { prop: 'error', type: 'string', initialValue: '', libraryValue: '' },
44 | { prop: 'size', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
45 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
46 | {
47 | prop: 'variant',
48 | type: 'segmented',
49 | data: [
50 | { value: 'filled', label: 'Filled' },
51 | { value: 'outline', label: 'Outline' },
52 | ],
53 | initialValue: '',
54 | libraryValue: '',
55 | },
56 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
57 | ],
58 | };
59 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/checkbox-group-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Checkbox, CheckboxGroupProps, Group } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Checkbox, Group } from '@mantine/core';
6 |
7 |
8 | function Demo() {
9 | return (
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | );
22 | }
23 | `;
24 |
25 | function Wrapper(props: Partial) {
26 | return (
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | );
36 | }
37 |
38 | export const checkboxGroupDemo: MantineDemo = {
39 | type: 'configurator',
40 | component: Wrapper,
41 | code,
42 | centered: true,
43 | maxWidth: '100%',
44 | controls: [
45 | {
46 | prop: 'label',
47 | type: 'string',
48 | initialValue: 'Select your favorite frameworks/libraries',
49 | libraryValue: '',
50 | },
51 | { prop: 'description', type: 'string', initialValue: 'This is anonymous', libraryValue: '' },
52 | { prop: 'error', type: 'string', initialValue: '', libraryValue: '' },
53 | { prop: 'withAsterisk', type: 'boolean', initialValue: true, libraryValue: false },
54 | ],
55 | };
56 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/typography/list-demo.tsx:
--------------------------------------------------------------------------------
1 | import { List, ListProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: ListProps) {
5 | return (
6 |
7 | Clone or download repository from GitHub
8 | Install dependencies with yarn
9 | To start development server run npm start command
10 | Run tests to make sure your changes do not break the build
11 | Submit a pull request once you are done
12 |
13 | );
14 | }
15 |
16 | const code = `
17 | import { List } from '@mantine/core';
18 |
19 | function Demo() {
20 | return (
21 |
22 | Clone or download repository from GitHub
23 | Install dependencies with yarn
24 | To start development server run npm start command
25 | Run tests to make sure your changes do not break the build
26 | Submit a pull request once you are done
27 |
28 | );
29 | }
30 | `;
31 |
32 | export const listDemo: MantineDemo = {
33 | type: 'configurator',
34 | component: Wrapper,
35 | code,
36 | controls: [
37 | {
38 | prop: 'type',
39 | type: 'segmented',
40 | data: [
41 | { value: 'unordered', label: 'Unordered' },
42 | { value: 'ordered', label: 'Ordered' },
43 | ],
44 | initialValue: 'unordered',
45 | libraryValue: 'unordered',
46 | },
47 | { prop: 'size', type: 'size', libraryValue: 'md', initialValue: 'md' },
48 | { prop: 'withPadding', type: 'boolean', libraryValue: false, initialValue: false },
49 | ],
50 | };
51 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/donot-chart-demo.tsx:
--------------------------------------------------------------------------------
1 | import { DonutChart } from '@mantine/charts';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { data, dataCode } from './data/_donut-data';
4 |
5 | const code = `
6 | import { DonutChart } from '@mantine/charts';
7 | import { data } from './data';
8 |
9 | function Demo() {
10 | return ;
11 | }
12 | `;
13 |
14 | function Wrapper(props: any) {
15 | return ;
16 | }
17 |
18 | export const donutChartDemo: MantineDemo = {
19 | type: 'configurator',
20 | component: Wrapper,
21 | code: [
22 | { fileName: 'Demo.tsx', code, language: 'tsx' },
23 | { fileName: 'data.ts', code: dataCode, language: 'tsx' },
24 | ],
25 | centered: true,
26 | controls: [
27 | {
28 | type: 'number',
29 | prop: 'size',
30 | initialValue: 160,
31 | min: 80,
32 | max: 300,
33 | step: 1,
34 | libraryValue: '__',
35 | },
36 | {
37 | type: 'number',
38 | prop: 'thickness',
39 | initialValue: 20,
40 | min: 2,
41 | max: 30,
42 | step: 1,
43 | libraryValue: '__',
44 | },
45 | {
46 | type: 'number',
47 | prop: 'paddingAngle',
48 | initialValue: 10,
49 | min: 0,
50 | max: 30,
51 | step: 1,
52 | libraryValue: '__',
53 | },
54 | {
55 | type: 'number',
56 | prop: 'strokeWidth',
57 | initialValue: 1,
58 | min: 0,
59 | max: 5,
60 | step: 0.1,
61 | libraryValue: '__',
62 | },
63 | { type: 'boolean', prop: 'withLabels', initialValue: true, libraryValue: '__' },
64 | { type: 'boolean', prop: 'withLabelsLine', initialValue: true, libraryValue: '__' }
65 | ],
66 | };
67 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/inputs/checkbox-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Checkbox, CheckboxProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Checkbox } from '@mantine/core';
6 |
7 |
8 | function Demo() {
9 | return (
10 |
14 | );
15 | }
16 | `;
17 |
18 | export const checkboxDemo: MantineDemo = {
19 | type: 'configurator',
20 | component: (props: CheckboxProps) => ,
21 | code,
22 | centered: true,
23 | controls: [
24 | {
25 | prop: 'labelPosition',
26 | type: 'segmented',
27 | data: [
28 | { value: 'right', label: 'Right' },
29 | { value: 'left', label: 'Left' },
30 | ],
31 | initialValue: 'right',
32 | libraryValue: 'right',
33 | },
34 | { prop: 'label', type: 'string', initialValue: 'I agree to sell my privacy', libraryValue: '' },
35 | { prop: 'description', type: 'string', initialValue: '', libraryValue: '' },
36 | { prop: 'error', type: 'string', initialValue: '', libraryValue: '' },
37 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
38 | {
39 | prop: 'variant',
40 | type: 'segmented',
41 | data: [
42 | { value: 'filled', label: 'Filled' },
43 | { value: 'outline', label: 'Outline' },
44 | ],
45 | initialValue: 'filled',
46 | libraryValue: 'filled',
47 | },
48 | { prop: 'radius', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
49 | { prop: 'size', type: 'size', initialValue: 'sm', libraryValue: 'sm' },
50 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
51 | { prop: 'indeterminate', type: 'boolean', initialValue: false, libraryValue: false },
52 | ],
53 | };
54 |
--------------------------------------------------------------------------------
/src/feature/blocks/components/component-canvas/color-control.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import { IconColorPicker } from "@tabler/icons-react";
3 | import { ColorSwatch, Group, Popover, useMantineTheme, CheckIcon, rem } from "@mantine/core";
4 |
5 | interface ColorControlProps {
6 | onChange(color: string): void;
7 | value: string;
8 | }
9 |
10 | export function ColorControl({ onChange, value }: ColorControlProps) {
11 | const [opened, setOpened] = useState(false);
12 | const theme = useMantineTheme();
13 | const colors = Object.keys(theme.colors).map((color) => ({
14 | swatch: theme.colors[color][6],
15 | color,
16 | }));
17 |
18 | const swatches = colors.map(({ color, swatch }) => (
19 | onChange(color)}
23 | key={color}
24 | color={swatch}
25 | size={22}
26 | style={{ color: theme.white, cursor: "pointer" }}
27 | >
28 | {value === color && }
29 |
30 | ));
31 |
32 | return (
33 | setOpened(false)}
36 | transitionProps={{ duration: 0 }}
37 | width={152}
38 | position="bottom-end"
39 | withArrow
40 | >
41 |
42 | setOpened((o) => !o)}
47 | size={22}
48 | style={{ display: "block", cursor: "pointer" }}
49 | >
50 |
51 |
52 |
53 |
54 | {swatches}
55 |
56 |
57 | );
58 | }
59 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/sparkline-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Sparkline } from '@mantine/charts';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Sparkline } from '@mantine/charts';
6 |
7 |
8 | function Demo() {
9 | return (
10 |
16 | );
17 | }
18 | `;
19 |
20 | function Wrapper(props: any) {
21 | return ;
22 | }
23 |
24 | export const sparklineDemo: MantineDemo = {
25 | type: 'configurator',
26 | component: Wrapper,
27 | code,
28 | centered: true,
29 | controls: [
30 | {
31 | type: 'select',
32 | prop: 'curveType',
33 | initialValue: 'linear',
34 | libraryValue: null,
35 | data: [
36 | { value: 'bump', label: 'bump' },
37 | { value: 'linear', label: 'linear' },
38 | { value: 'natural', label: 'natural' },
39 | { value: 'monotone', label: 'monotone' },
40 | { value: 'step', label: 'step' },
41 | { value: 'stepBefore', label: 'stepBefore' },
42 | { value: 'stepAfter', label: 'stepAfter' },
43 | ],
44 | },
45 | { type: 'color', prop: 'color', initialValue: '', libraryValue: '' },
46 | {
47 | type: 'number',
48 | prop: 'fillOpacity',
49 | initialValue: 0.6,
50 | libraryValue: null,
51 | min: 0,
52 | max: 1,
53 | step: 0.01,
54 | },
55 | {
56 | type: 'boolean',
57 | prop: 'withGradient',
58 | initialValue: true,
59 | libraryValue: true,
60 | },
61 | {
62 | type: 'number',
63 | prop: 'strokeWidth',
64 | initialValue: 2,
65 | libraryValue: null,
66 | step: 0.1,
67 | min: 0.5,
68 | max: 5,
69 | },
70 | ],
71 | };
72 |
--------------------------------------------------------------------------------
/src/feature/blocks/components/component-canvas/component-canvas.module.css:
--------------------------------------------------------------------------------
1 | .canvas {
2 | border-radius: var(--mantine-radius-md);
3 | border: rem(1px) solid var(--mantine-color-default-border);
4 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6));
5 |
6 | &:not(:first-of-type) {
7 | margin-top: calc(var(--mantine-spacing-xl) * 2);
8 | }
9 | }
10 |
11 | .body {
12 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-9));
13 | padding: var(--mantine-spacing-xs) var(--mantine-spacing-md);
14 | border-bottom-right-radius: calc(var(--mantine-radius-md) - rem(1px));
15 | border-bottom-left-radius: calc(var(--mantine-radius-md) - rem(1px));
16 |
17 | @media (max-width: $mantine-breakpoint-sm) {
18 | padding: 0;
19 | }
20 | }
21 |
22 | .bodyRaw {
23 | padding: 0;
24 |
25 | & .preview {
26 | padding: rem(4px);
27 | border-top-right-radius: 0;
28 | border-top-left-radius: 0;
29 | }
30 | }
31 |
32 | .bodyWithCode {
33 | padding: 0;
34 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-8));
35 | }
36 |
37 | .code {
38 | border-bottom-right-radius: calc(var(--mantine-radius-md) - rem(1px));
39 | border-bottom-left-radius: calc(var(--mantine-radius-md) - rem(1px));
40 | border-top-right-radius: 0;
41 | border-top-left-radius: 0;
42 | }
43 |
44 | .preview {
45 | background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7));
46 | padding: var(--mantine-spacing-md);
47 | border-radius: var(--mantine-radius-md);
48 | position: relative;
49 |
50 | &[data-dimmed] {
51 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
52 | }
53 |
54 | @media (max-width: $mantine-breakpoint-sm) {
55 | padding: var(--mantine-spacing-xs);
56 | border-top-right-radius: 0;
57 | border-top-left-radius: 0;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/pie-chart-demo.tsx:
--------------------------------------------------------------------------------
1 | import { PieChart } from '@mantine/charts';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { data, dataCode } from './data/_pie-data';
4 |
5 | const code = `
6 | import { PieChart } from '@mantine/charts';
7 | import { data } from './data';
8 |
9 | function Demo() {
10 | return ;
11 | }
12 | `;
13 |
14 | function Wrapper(props: any) {
15 | return ;
16 | }
17 |
18 | export const pieChartDemo: MantineDemo = {
19 | type: 'configurator',
20 | component: Wrapper,
21 | code: [
22 | { fileName: 'Demo.tsx', code, language: 'tsx' },
23 | { fileName: 'data.ts', code: dataCode, language: 'tsx' },
24 | ],
25 | centered: true,
26 | controls: [
27 | {
28 | type: 'segmented',
29 | prop: 'labelsPosition',
30 | initialValue: 'outside',
31 | libraryValue: '__',
32 | data: ['inside', 'outside'],
33 | },
34 | {
35 | type: 'segmented',
36 | prop: 'labelsType',
37 | initialValue: 'value',
38 | libraryValue: '__',
39 | data: ['value', 'percent'],
40 | },
41 | {
42 | type: 'number',
43 | prop: 'strokeWidth',
44 | initialValue: 1,
45 | min: 0,
46 | max: 2,
47 | step: 0.1,
48 | libraryValue: '__',
49 | },
50 | {
51 | type: 'number',
52 | prop: 'size',
53 | initialValue: 160,
54 | min: 80,
55 | max: 300,
56 | step: 1,
57 | libraryValue: '__',
58 | },
59 | { type: 'boolean', prop: 'withLabels', initialValue: true, libraryValue: '__' },
60 | { type: 'boolean', prop: 'withLabelsLine', initialValue: true, libraryValue: '__' },
61 | ],
62 | };
63 |
--------------------------------------------------------------------------------
/src/feature/blocks/lib/pricing1/pricing1.module.css:
--------------------------------------------------------------------------------
1 | .pricingWrapper {
2 | background-color: var(--mantine-body-color);
3 | padding: 4rem 0;
4 | }
5 |
6 | .mainTitle {
7 | font-size: 3rem;
8 | font-weight: 900;
9 | background: linear-gradient(180deg, var(--mantine-primary-color-filled), var(--mantine-primary-color-8));
10 | -webkit-background-clip: text;
11 | -webkit-text-fill-color: transparent;
12 | }
13 |
14 | .mainSubtitle {
15 | font-size: 1.2rem;
16 | margin-bottom: 2rem;
17 | }
18 |
19 | .billingSwitch {
20 | transform: scale(1.2);
21 | margin: 0 1rem;
22 | }
23 |
24 | .pricingCard {
25 | background-color: var(--mantine-body-color);
26 | box-shadow: 0 15px 30px rgba(0, 0, 0, 0.05);
27 | transition: all 0.3s ease;
28 | padding: 2rem;
29 | position: relative;
30 | height: 100%;
31 | }
32 |
33 | .pricingCard:hover {
34 | transform: translateY(-10px);
35 | box-shadow: 0 25px 50px rgba(0, 0, 0, 0.1);
36 | }
37 |
38 | .recommendedCard {
39 | border-color: var(--mantine-color-default-border);
40 | }
41 |
42 | .recommendedBadge {
43 | position: absolute;
44 | top: -12px;
45 | right: 4px;
46 | background-color: var(--mantine-primary-color-light);
47 | color: var(--mantine-color-text);
48 | padding: 0rem 0.6rem;
49 | border-radius: 99px;
50 | font-size: 0.6rem;
51 | font-weight: bold;
52 | text-transform: uppercase;
53 | z-index: 10;
54 | letter-spacing: 2px;
55 | line-height: rem(24px);
56 |
57 | background: linear-gradient(45deg, var(--mantine-primary-color-filled), var(--mantine-primary-color-0));
58 | -webkit-background-clip: text;
59 | -webkit-text-fill-color: transparent;
60 | }
61 |
62 | .planTitle {
63 | color: var(--mantine-primary-color-4);
64 | }
65 |
66 | .price {
67 | background: linear-gradient(45deg, var(--mantine-primary-color-8), var(--mantine-primary-color-4));
68 | -webkit-background-clip: text;
69 | -webkit-text-fill-color: transparent;
70 | }
71 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/overlays/dialog-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Dialog, Group, Text, TextInput } from '@mantine/core';
2 | import { useDisclosure } from '@mantine/hooks';
3 | import { MantineDemo } from '../../../mantine/demo';
4 | // import { MantineDemo } from '../../../mantine/demo';
5 |
6 | const code = `
7 | import { useDisclosure } from '@mantine/hooks';
8 | import { Dialog, Group, Button, TextInput, Text } from '@mantine/core';
9 |
10 | function Demo() {
11 | const [opened, { toggle, close }] = useDisclosure(false);
12 |
13 | return (
14 | <>
15 |
16 |
17 |
18 |
19 |
29 | >
30 | );
31 | }
32 | `;
33 |
34 | function Demo() {
35 | const [opened, { toggle, close }] = useDisclosure(false);
36 |
37 | return (
38 | <>
39 |
40 |
41 |
42 |
43 |
53 | >
54 | );
55 | }
56 |
57 | export const dialogDemo: MantineDemo = {
58 | type: 'code',
59 | component: Demo,
60 | code,
61 | };
62 |
--------------------------------------------------------------------------------
/src/components/custom/theme-example-cards/mantine-cards.tsx:
--------------------------------------------------------------------------------
1 | import { Grid, Group, SimpleGrid, Stack } from "@mantine/core";
2 | import { CardsActivityGoal } from "./activity-goal";
3 | import { CardsCalendar } from "./calendar";
4 | import { CardsChat } from "./chat";
5 | import { CardsMetric } from "./metric";
6 | import { CardsStats } from "./stats";
7 | import { CardsTeamMembers } from "./team-members";
8 | import { CardsCookieSettings } from "./cookie-settings";
9 | import { CardsPaymentMethod } from "./payment-method";
10 | import { CardsCreateAccount } from "./create-account";
11 | import { CardsReportIssue } from "./report-issue";
12 | import { CardsDataTable } from "./data-table";
13 | import { CardsShare } from "./share";
14 | import { useMediaQuery } from "@mantine/hooks";
15 |
16 | const MantineCards = () => {
17 |
18 | const isMobile = useMediaQuery ('(max-width: 425px)');
19 | return (
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | );
53 | };
54 |
55 | export default MantineCards;
56 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/feedback/ring-progress-demo.tsx:
--------------------------------------------------------------------------------
1 | import { RingProgress, RingProgressProps, Text } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Wrapper(props: RingProgressProps) {
5 | return (
6 |
10 | Hover sections to see tooltips
11 |
12 | }
13 | sections={[
14 | { value: 40, color: 'cyan', tooltip: 'Documents – 40 Gb' },
15 | { value: 25, color: 'orange', tooltip: 'Apps – 25 Gb' },
16 | { value: 15, color: 'grape', tooltip: 'Other – 15 Gb' },
17 | ]}
18 | />
19 | );
20 | }
21 |
22 | const code = `
23 | import { RingProgress } from '@mantine/core';
24 |
25 | function Demo() {
26 | return (
27 |
31 | Hover sections to see tooltips
32 |
33 | }
34 | sections={[
35 | { value: 40, color: 'cyan', tooltip: 'Documents – 40 Gb' },
36 | { value: 25, color: 'orange', tooltip: 'Apps – 25 Gb' },
37 | { value: 15, color: 'grape', tooltip: 'Other – 15 Gb' },
38 | ]}
39 | />
40 | )
41 | }
42 | `;
43 |
44 | export const ringProgressDemo: MantineDemo = {
45 | type: 'configurator',
46 | component: Wrapper,
47 | centered: true,
48 | code,
49 | controls: [
50 | {
51 | prop: 'size',
52 | type: 'number',
53 | initialValue: 180,
54 | step: 10,
55 | min: 60,
56 | max: 400,
57 | libraryValue: '__',
58 | },
59 | {
60 | prop: 'thickness',
61 | type: 'number',
62 | initialValue: 12,
63 | step: 1,
64 | min: 1,
65 | max: 40,
66 | libraryValue: '__',
67 | },
68 | { prop: 'roundCaps', type: 'boolean', initialValue: true, libraryValue: false },
69 | ],
70 | };
71 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/data-display/spoiler-demo.tsx:
--------------------------------------------------------------------------------
1 |
2 | import { Box, Spoiler, SpoilerProps, Text } from '@mantine/core';
3 | import { MantineDemo } from '../../../mantine/demo';
4 |
5 | const content = (
6 |
7 |
18 |
19 | We Butter the Bread with Butter was founded in 2007 by Marcel Neumann, who was originally
20 | guitarist for Martin Kesici's band, and Tobias Schultka. The band was originally meant as
21 | a joke, but progressed into being a more serious musical duo. The name for the band has no
22 | particular meaning, although its origins were suggested from when the two original members
23 | were driving in a car operated by Marcel Neumann and an accident almost occurred. Neumann
24 | found Schultka "so funny that he briefly lost control of the vehicle." Many of their
25 | songs from this point were covers of German folk tales and nursery rhymes.
26 |
27 |
28 | );
29 |
30 | function Wrapper(props: Partial) {
31 | return (
32 |
33 |
34 | {content}
35 |
36 |
37 | );
38 | }
39 |
40 |
41 | const code = `
42 | import { Spoiler } from '@mantine/core';
43 |
44 | function Demo() {
45 | return (
46 |
47 | {/* Content here */}
48 |
49 | );
50 | }
51 | `;
52 |
53 | function Demo() {
54 | return ;
55 | }
56 |
57 | export const spoilerDemo: MantineDemo = {
58 | type: 'code',
59 | code,
60 | component: Demo,
61 | };
62 |
--------------------------------------------------------------------------------
/src/utils/input-controls.ts:
--------------------------------------------------------------------------------
1 | import { ConfiguratorControlOptions } from "../components/mantine/demo";
2 |
3 |
4 | export const inputOnlyControls: ConfiguratorControlOptions[] = [
5 | {
6 | type: 'segmented',
7 | prop: 'variant',
8 | data: ['default', 'filled', 'unstyled'],
9 | initialValue: 'default',
10 | libraryValue: 'default',
11 | },
12 | { type: 'size', prop: 'size', initialValue: 'sm', libraryValue: 'sm' },
13 | { type: 'size', prop: 'radius', initialValue: 'sm', libraryValue: 'sm' },
14 | { type: 'boolean', prop: 'disabled', initialValue: false, libraryValue: false },
15 | { type: 'boolean', prop: 'error', initialValue: false, libraryValue: false },
16 | ];
17 |
18 | export const inputWrapperOnlyControls: ConfiguratorControlOptions[] = [
19 | { type: 'string', prop: 'label', initialValue: 'Input label', libraryValue: null },
20 | { type: 'boolean', prop: 'withAsterisk', initialValue: false, libraryValue: false },
21 | { type: 'string', prop: 'description', initialValue: 'Input description', libraryValue: null },
22 | { type: 'string', prop: 'error', initialValue: 'Input error', libraryValue: null },
23 | { type: 'size', prop: 'size', initialValue: 'sm', libraryValue: 'sm' },
24 | ];
25 |
26 | export const inputControls: ConfiguratorControlOptions[] = [
27 | {
28 | type: 'segmented',
29 | prop: 'variant',
30 | data: ['default', 'filled', 'unstyled'],
31 | initialValue: '',
32 | libraryValue: '',
33 | },
34 | { type: 'size', prop: 'size', initialValue: 'sm', libraryValue: 'sm' },
35 | { type: 'size', prop: 'radius', initialValue: 'sm', libraryValue: 'sm' },
36 | { type: 'string', prop: 'label', initialValue: 'Input label', libraryValue: '' },
37 | { type: 'boolean', prop: 'withAsterisk', initialValue: false, libraryValue: false },
38 | { type: 'string', prop: 'description', initialValue: 'Input description', libraryValue: '' },
39 | { type: 'string', prop: 'error', initialValue: '', libraryValue: '' },
40 | { prop: "disabled", type: "boolean", initialValue: false, libraryValue: false },
41 | ];
42 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/typography/text-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Text } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Text } from '@mantine/core';
6 |
7 | function Demo() {
8 | return (
9 | <>
10 | Extra small text
11 | Small text
12 | Default text
13 | Large text
14 | Extra large text
15 | Semibold
16 | Bold
17 | Italic
18 | Underlined
19 | Strikethrough
20 | Dimmed text
21 | Blue text
22 | Teal 4 text
23 | Uppercase
24 | capitalized text
25 | Aligned to center
26 | Aligned to right
27 | >
28 | );
29 | }
30 | `;
31 |
32 | function Demo() {
33 | return (
34 | <>
35 | Extra small text
36 | Small text
37 | Default text
38 | Large text
39 | Extra large text
40 | Semibold
41 | Bold
42 | Italic
43 | Underlined
44 | Strikethrough
45 | Dimmed text
46 | Blue text
47 | Teal 4 text
48 | Uppercase
49 | capitalized text
50 | Aligned to center
51 | Aligned to right
52 | >
53 | );
54 | }
55 |
56 | export const textDemo: MantineDemo = {
57 | type: 'code',
58 | code,
59 | component: Demo,
60 | };
61 |
--------------------------------------------------------------------------------
/src/themes/mantine/mantine-theme.ts:
--------------------------------------------------------------------------------
1 | import { Card, Container, createTheme, Paper, rem, Select } from "@mantine/core";
2 | import type { MantineThemeOverride } from "@mantine/core";
3 |
4 | const CONTAINER_SIZES: Record = {
5 | xxs: rem("200px"),
6 | xs: rem("300px"),
7 | sm: rem("400px"),
8 | md: rem("500px"),
9 | lg: rem("600px"),
10 | xl: rem("1400px"),
11 | xxl: rem("1600px"),
12 | };
13 |
14 | export const mantineTheme: MantineThemeOverride = createTheme({
15 | /** Put your mantine theme override here */
16 | fontSizes: {
17 | xs: rem("12px"),
18 | sm: rem("14px"),
19 | md: rem("16px"),
20 | lg: rem("18px"),
21 | xl: rem("20px"),
22 | "2xl": rem("24px"),
23 | "3xl": rem("30px"),
24 | "4xl": rem("36px"),
25 | "5xl": rem("48px"),
26 | },
27 | spacing: {
28 | "3xs": rem("4px"),
29 | "2xs": rem("8px"),
30 | xs: rem("10px"),
31 | sm: rem("12px"),
32 | md: rem("16px"),
33 | lg: rem("20px"),
34 | xl: rem("24px"),
35 | "2xl": rem("28px"),
36 | "3xl": rem("32px"),
37 | },
38 | primaryColor: "blue",
39 | components: {
40 | /** Put your mantine component override here */
41 | Container: Container.extend({
42 | vars: (_, { size, fluid }) => ({
43 | root: {
44 | "--container-size": fluid
45 | ? "100%"
46 | : size !== undefined && size in CONTAINER_SIZES
47 | ? CONTAINER_SIZES[size]
48 | : rem(size),
49 | },
50 | }),
51 | }),
52 | Paper: Paper.extend({
53 | defaultProps: {
54 | p: "md",
55 | shadow: "xl",
56 | radius: "md",
57 | withBorder: true,
58 | },
59 | }),
60 |
61 | Card: Card.extend({
62 | defaultProps: {
63 | p: "xl",
64 | shadow: "xl",
65 | radius: "var(--mantine-radius-default)",
66 | withBorder: true,
67 | },
68 | }),
69 | Select: Select.extend({
70 | defaultProps: {
71 | checkIconPosition: "right",
72 | },
73 | }),
74 | },
75 | other: {
76 | style: "mantine",
77 | },
78 | });
79 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/typography/table-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Table, TableProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const elements = [
5 | { position: 6, mass: 12.011, symbol: 'C', name: 'Carbon' },
6 | { position: 7, mass: 14.007, symbol: 'N', name: 'Nitrogen' },
7 | { position: 39, mass: 88.906, symbol: 'Y', name: 'Yttrium' },
8 | { position: 56, mass: 137.33, symbol: 'Ba', name: 'Barium' },
9 | { position: 58, mass: 140.12, symbol: 'Ce', name: 'Cerium' },
10 | ];
11 |
12 | function Wrapper(props: TableProps) {
13 | return (
14 |
15 |
16 |
17 | Element position
18 | Element name
19 | Symbol
20 | Atomic mass
21 |
22 |
23 |
24 | {elements.map((element) => (
25 |
26 | {element.position}
27 | {element.name}
28 | {element.symbol}
29 | {element.mass}
30 |
31 | ))}
32 |
33 |
34 | );
35 | }
36 |
37 | const code = `
38 | import { Table } from '@mantine/core';
39 |
40 | function Demo() {
41 | return (
42 |
43 | {/* {...rows} */}
44 |
45 | );
46 | }
47 | `;
48 |
49 | export const tableDemo: MantineDemo = {
50 | type: 'configurator',
51 | component: Wrapper,
52 | code,
53 | controls: [
54 | { prop: 'striped', type: 'boolean', initialValue: false, libraryValue: false },
55 | { prop: 'highlightOnHover', type: 'boolean', initialValue: false, libraryValue: false },
56 | { prop: 'withTableBorder', type: 'boolean', initialValue: false, libraryValue: false },
57 | { prop: 'withColumnBorders', type: 'boolean', initialValue: false, libraryValue: false },
58 | { prop: 'withRowBorders', type: 'boolean', initialValue: true, libraryValue: true },
59 | ],
60 | };
61 |
--------------------------------------------------------------------------------
/src/components/custom/theme-example-cards/cookie-settings.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Card, Text, Switch, Group, Title } from '@mantine/core';
2 |
3 | export function CardsCookieSettings() {
4 | return (
5 |
6 |
7 | Cookie Settings
8 | Manage your cookie settings here.
9 |
10 |
11 |
12 |
13 | Strictly Necessary
14 |
15 | These cookies are essential in order to use the website and use its features.
16 |
17 |
18 |
19 |
20 |
21 |
22 | Functional Cookies
23 |
24 | These cookies allow the website to provide personalized functionality.
25 |
26 |
27 |
28 |
29 |
30 |
31 | Performance Cookies
32 |
33 | These cookies help to improve the performance of the website.
34 |
35 |
36 |
37 |
38 |
39 |
40 |
43 |
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/src/feature/blocks/components/component-canvas/component-canvas.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import cx from "clsx";
4 | import { useState } from "react";
5 | import { MantineThemeProvider, Box } from "@mantine/core";
6 | import { getCodeFileIcon } from "@mantinex/dev-icons";
7 | import * as UiComponents from "../../lib";
8 | import { UiComponent } from "../../data/types";
9 | import { ComponentPreview } from "../component-preview/component-preview";
10 | import { CanvasHeader } from "./canvas-header";
11 |
12 | import classes from "./component-canvas.module.css";
13 | import { CodeHighlightTabs } from "@mantine/code-highlight";
14 |
15 | export function ComponentCanvas(props: UiComponent & { zindex: number }) {
16 | const [state, setState] = useState("preview");
17 | const [primaryColor, setPrimaryColor] = useState("blue");
18 | const Component: any = UiComponents[props.component as keyof typeof UiComponents];
19 |
20 | return (
21 |
22 |
29 |
30 |
36 | {state === "preview" ? (
37 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | ) : (
50 |
51 |
52 |
53 | )}
54 |
55 |
56 | );
57 | }
58 |
--------------------------------------------------------------------------------
/src/components/custom/theme-example-cards/report-issue.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Card, Group, Select, Stack, Text, TextInput, Textarea, Title } from "@mantine/core";
2 | import * as React from "react";
3 |
4 | export function CardsReportIssue() {
5 | const id = React.useId();
6 |
7 | return (
8 |
9 |
10 | Report an issue
11 |
12 | What area are you having problems with?
13 |
14 |
15 |
16 |
17 |
30 |
31 |
47 |
48 |
49 |
50 |
51 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | );
63 | }
64 |
--------------------------------------------------------------------------------
/src/components/mantine/demo/ConfiguratorDemo/controls/ColorWheelIcon.tsx:
--------------------------------------------------------------------------------
1 | import { rem } from '@mantine/core';
2 |
3 | export function ColorWheelIcon() {
4 | return (
5 |
57 | );
58 | }
59 |
--------------------------------------------------------------------------------
/src/components/ui/navbar/navbar-links-group.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Collapse, Group, rem, Text, UnstyledButton } from "@mantine/core";
2 | import { IconChevronRight } from "@tabler/icons-react";
3 | import { useState } from "react";
4 | import { NavbarProps } from "./navbar";
5 | import classes from "./navbar.module.scss"
6 |
7 |
8 | interface NavbarLinksGroupProps extends NavbarProps {
9 | selected: string;
10 | setSelected: (value: string) => void;
11 | }
12 |
13 | export default function NavbarLinksGroup({ label, initiallyOpened, links, selected, setSelected }: NavbarLinksGroupProps) {
14 | const hasLinks = Array.isArray(links);
15 | const [opened, setOpened] = useState(initiallyOpened || false);
16 |
17 | const scrollToSection = (id: string) => {
18 | setSelected(id);
19 | const element = document.getElementById(id);
20 | if (element) {
21 | element.scrollIntoView({ behavior: 'smooth' });
22 | }
23 |
24 | }
25 |
26 | const items = (hasLinks ? links : []).map((link) => (
27 | scrollToSection(link.value)}
31 | style={{ backgroundColor: selected === link.value ? 'var(--mantine-color-default-hover)' : undefined }}
32 | >
33 | {link.label}
34 |
35 | ));
36 |
37 | return (
38 | <>
39 | setOpened((o) => !o)} className={classes.control}>
40 |
41 |
42 | {label}
43 |
44 | {hasLinks && (
45 |
54 | )}
55 |
56 |
57 | {hasLinks ?
58 |
59 | {items}
60 |
61 | : null}
62 | >
63 | );
64 | }
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/bar-chart-demo.tsx:
--------------------------------------------------------------------------------
1 | import { BarChart } from '@mantine/charts';
2 | import { MantineDemo } from '../../../mantine/demo';
3 | import { data, dataCode } from './data/_bar-data';
4 |
5 | const code = `
6 | import { BarChart } from '@mantine/charts';
7 | import { data } from './data';
8 |
9 |
10 | function Demo() {
11 | return (
12 |
23 | );
24 | }
25 | `;
26 |
27 | function Wrapper(props: any) {
28 | return (
29 |
40 | );
41 | }
42 |
43 | export const barchartDemo: MantineDemo = {
44 | type: 'configurator',
45 | component: Wrapper,
46 | code: [
47 | { code, language: 'tsx', fileName: 'Demo.tsx' },
48 | { code: dataCode, language: 'tsx', fileName: 'data.ts' },
49 | ],
50 | controls: [
51 | {
52 | type: 'segmented',
53 | prop: 'tickLine',
54 | initialValue: 'y',
55 | libraryValue: '__',
56 | transformLabel: false,
57 | data: [
58 | { value: 'x', label: 'x' },
59 | { value: 'y', label: 'y' },
60 | { value: 'xy', label: 'xy' },
61 | { value: 'none', label: 'none' },
62 | ],
63 | },
64 | {
65 | type: 'segmented',
66 | prop: 'gridAxis',
67 | initialValue: 'x',
68 | libraryValue: 'x',
69 | transformLabel: false,
70 | data: [
71 | { value: 'x', label: 'x' },
72 | { value: 'y', label: 'y' },
73 | { value: 'xy', label: 'xy' },
74 | { value: 'none', label: 'none' },
75 | ],
76 | },
77 | {
78 | type: 'boolean',
79 | prop: 'withXAxis',
80 | initialValue: true,
81 | libraryValue: true,
82 | },
83 | {
84 | type: 'boolean',
85 | prop: 'withYAxis',
86 | initialValue: true,
87 | libraryValue: true,
88 | },
89 | ],
90 | };
91 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/data-display/card-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Badge, Button, Card, Group, Image, Text } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | const code = `
5 | import { Card, Image, Text, Badge, Button, Group } from '@mantine/core';
6 |
7 | function Demo() {
8 | return (
9 |
10 |
11 |
17 |
18 |
19 |
20 | Norway Fjord Adventures
21 | On Sale
22 |
23 |
24 |
25 | With Fjord Tours you can explore more of the magical fjord landscapes with tours and
26 | activities on and around the fjords of Norway
27 |
28 |
29 |
32 |
33 | );
34 | }
35 |
36 | `;
37 |
38 | function Demo() {
39 | return (
40 |
41 |
42 |
48 |
49 |
50 |
51 | Norway Fjord Adventures
52 | On Sale
53 |
54 |
55 |
56 | With Fjord Tours you can explore more of the magical fjord landscapes with tours and
57 | activities on and around the fjords of Norway
58 |
59 |
60 |
63 |
64 | );
65 | }
66 |
67 | export const cardDemo: MantineDemo = {
68 | type: 'code',
69 | code,
70 | component: Demo,
71 | centered: true,
72 | maxWidth: 340,
73 | dimmed: true,
74 | };
75 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/data-display/indicator-demo.tsx:
--------------------------------------------------------------------------------
1 | import { Avatar, Indicator, IndicatorProps } from '@mantine/core';
2 | import { MantineDemo } from '../../../mantine/demo';
3 |
4 | function Demo(props: IndicatorProps) {
5 | return (
6 |
7 |
12 |
13 | );
14 | }
15 |
16 | const code = `
17 | import { Indicator, Avatar } from '@mantine/core';
18 |
19 | function Demo() {
20 | return (
21 |
22 |
27 |
28 | );
29 | }
30 | `;
31 |
32 | export const indicatorDemo: MantineDemo = {
33 | type: 'configurator',
34 | component: Demo,
35 | code,
36 | centered: true,
37 | controls: [
38 | { prop: 'color', type: 'color', initialValue: '', libraryValue: '' },
39 | {
40 | prop: 'position',
41 | type: 'select',
42 | data: [
43 | { value: 'top-start', label: 'top-start' },
44 | { value: 'top-center', label: 'top-center' },
45 | { value: 'top-end', label: 'top-end' },
46 | { value: 'middle-start', label: 'middle-start' },
47 | { value: 'middle-center', label: 'middle-center' },
48 | { value: 'middle-end', label: 'middle-end' },
49 | { value: 'bottom-start', label: 'bottom-start' },
50 | { value: 'bottom-center', label: 'bottom-center' },
51 | { value: 'bottom-end', label: 'bottom-end' },
52 | ],
53 | initialValue: 'top-end',
54 | libraryValue: 'top-end',
55 | },
56 | { prop: 'label', type: 'string', initialValue: '', libraryValue: '' },
57 | { prop: 'offset', type: 'number', initialValue: 0, libraryValue: 10, step: 1, min: 0, max: 56 },
58 | { prop: 'radius', type: 'size', initialValue: 'xl', libraryValue: 'xl' },
59 | { prop: 'size', type: 'number', initialValue: 10, libraryValue: 10, step: 1, min: 6, max: 30 },
60 | { prop: 'disabled', type: 'boolean', initialValue: false, libraryValue: false },
61 | { prop: 'withBorder', type: 'boolean', initialValue: false, libraryValue: false },
62 | { prop: 'processing', type: 'boolean', initialValue: false, libraryValue: false },
63 | ],
64 | };
65 |
--------------------------------------------------------------------------------
/src/components/custom/components-demo/charts/data/_radar-data.ts:
--------------------------------------------------------------------------------
1 | export const data = [
2 | {
3 | product: 'Apples',
4 | sales: 120,
5 | },
6 | {
7 | product: 'Oranges',
8 | sales: 98,
9 | },
10 | {
11 | product: 'Tomatoes',
12 | sales: 86,
13 | },
14 | {
15 | product: 'Grapes',
16 | sales: 99,
17 | },
18 | {
19 | product: 'Bananas',
20 | sales: 85,
21 | },
22 | {
23 | product: 'Lemons',
24 | sales: 65,
25 | },
26 | ];
27 |
28 | export const dataCode = `
29 | export const data = [
30 | {
31 | product: 'Apples',
32 | sales: 120,
33 | },
34 | {
35 | product: 'Oranges',
36 | sales: 98,
37 | },
38 | {
39 | product: 'Tomatoes',
40 | sales: 86,
41 | },
42 | {
43 | product: 'Grapes',
44 | sales: 99,
45 | },
46 | {
47 | product: 'Bananas',
48 | sales: 85,
49 | },
50 | {
51 | product: 'Lemons',
52 | sales: 65,
53 | },
54 | ];
55 | `;
56 |
57 | export const multiData = [
58 | {
59 | product: 'Apples',
60 | 'Sales January': 120,
61 | 'Sales February': 100,
62 | },
63 | {
64 | product: 'Oranges',
65 | 'Sales January': 98,
66 | 'Sales February': 90,
67 | },
68 | {
69 | product: 'Tomatoes',
70 | 'Sales January': 86,
71 | 'Sales February': 70,
72 | },
73 | {
74 | product: 'Grapes',
75 | 'Sales January': 99,
76 | 'Sales February': 80,
77 | },
78 | {
79 | product: 'Bananas',
80 | 'Sales January': 85,
81 | 'Sales February': 120,
82 | },
83 | {
84 | product: 'Lemons',
85 | 'Sales January': 65,
86 | 'Sales February': 150,
87 | },
88 | ];
89 |
90 | export const multiDataCode = `
91 | export const data = [
92 | {
93 | product: 'Apples',
94 | 'Sales January': 120,
95 | 'Sales February': 100,
96 | },
97 | {
98 | product: 'Oranges',
99 | 'Sales January': 98,
100 | 'Sales February': 90,
101 | },
102 | {
103 | product: 'Tomatoes',
104 | 'Sales January': 86,
105 | 'Sales February': 70,
106 | },
107 | {
108 | product: 'Grapes',
109 | 'Sales January': 99,
110 | 'Sales February': 80,
111 | },
112 | {
113 | product: 'Bananas',
114 | 'Sales January': 85,
115 | 'Sales February': 120,
116 | },
117 | {
118 | product: 'Lemons',
119 | 'Sales January': 65,
120 | 'Sales February': 150,
121 | },
122 | ];`;
123 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mantine-modern-theme",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "engines": {
7 | "node": ">=20.9.0"
8 | },
9 | "scripts": {
10 | "dev": "next dev",
11 | "build": "tsc -b && next build",
12 | "start": "next start",
13 | "lint": "eslint .",
14 | "preview": "next preview",
15 | "compileTs": "node ./js/scripts/compileTs.cjs",
16 | "generateThemes": "node ./js/scripts/generateThemes.cjs",
17 | "generateCssVariableResolver": "node ./js/scripts/generateCssVariableResolver.cjs",
18 | "generateStyles": "node ./js/scripts/generateStyles.cjs",
19 | "generate": "npm run compileTs && npm run generateThemes && npm run generateCssVariableResolver && npm run generateStyles",
20 | "generateComponents": "node ./js/scripts/components.cjs"
21 | },
22 | "dependencies": {
23 | "@mantine/charts": "^7.15.2",
24 | "@mantine/code-highlight": "^7.15.2",
25 | "@mantine/core": "^7.15.2",
26 | "@mantine/dates": "^7.15.2",
27 | "@mantine/form": "^7.15.2",
28 | "@mantine/hooks": "^7.15.2",
29 | "@mantine/spotlight": "^7.15.2",
30 | "@mantinex/dev-icons": "^1.1.0",
31 | "@mantinex/mantine-header": "^1.1.0",
32 | "@mantinex/shiki": "^1.1.0",
33 | "@radix-ui/react-icons": "^1.3.0",
34 | "@tabler/icons-react": "^3.19.0",
35 | "@tanstack/react-router": "^1.82.1",
36 | "@tanstack/react-table": "^8.20.5",
37 | "clsx": "^2.1.1",
38 | "dayjs": "^1.11.13",
39 | "next": "^15.1.0",
40 | "react": "^18.3.1",
41 | "react-dom": "^18.3.1",
42 | "recharts": "^2.15.0",
43 | "sass": "^1.80.6",
44 | "sass-loader": "^16.0.3",
45 | "shiki": "^1.23.0",
46 | "shikiji": "^0.7.6"
47 | },
48 | "devDependencies": {
49 | "@eslint/js": "^9.11.1",
50 | "@tanstack/router-devtools": "^1.82.1",
51 | "@tanstack/router-plugin": "^1.81.9",
52 | "@types/node": "^22.9.1",
53 | "@types/react": "^18.3.10",
54 | "@types/react-dom": "^18.3.0",
55 | "autoprefixer": "^10.4.20",
56 | "eslint": "^9.11.1",
57 | "eslint-config-prettier": "^9.1.0",
58 | "eslint-plugin-react-hooks": "^5.1.0-rc.0",
59 | "eslint-plugin-react-refresh": "^0.4.12",
60 | "globals": "^15.9.0",
61 | "postcss": "^8.4.49",
62 | "postcss-preset-mantine": "^1.17.0",
63 | "postcss-simple-vars": "^7.0.1",
64 | "prettier": "3.3.3",
65 | "sass-embedded": "^1.81.0",
66 | "tailwindcss": "^3.4.15",
67 | "typescript": "^5.5.3",
68 | "typescript-eslint": "^8.7.0",
69 | "vite-plugin-node-polyfills": "^0.22.0"
70 | }
71 | }
72 |
--------------------------------------------------------------------------------