├── .eslintignore
├── .eslintrc.json
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .vscode
└── settings.json
├── README.md
├── app
├── [component]
│ ├── layout.tsx
│ └── page.tsx
├── layout.tsx
└── page.tsx
├── component-data
├── react
│ ├── shared
│ │ ├── 404
│ │ │ ├── App.js
│ │ │ ├── index.ts
│ │ │ └── styles.css
│ │ └── wrapper
│ │ │ ├── index.css
│ │ │ └── index.ts
│ ├── tailwind
│ │ └── inline
│ │ │ └── checkbox
│ │ │ ├── index.ts
│ │ │ └── styles.ts
│ └── vanilla_css
│ │ └── scoped
│ │ ├── accordion
│ │ ├── AccordionIcon.js
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── checkbox
│ │ ├── App.js
│ │ ├── CheckIcon.js
│ │ ├── MinusIcon.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── dialog
│ │ ├── App.js
│ │ ├── CloseIcon.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── hover-card
│ │ ├── App.js
│ │ ├── MapPinIcon.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── menu
│ │ ├── App.js
│ │ ├── RightIcon.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── number-input
│ │ ├── App.js
│ │ ├── ChevronDownIcon.js
│ │ ├── ChevronUpIcon.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── pagination
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── pin-input
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── popover
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── radio-group
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── range-slider
│ │ ├── App.js
│ │ └── index.ts
│ │ ├── rating-group
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── select
│ │ ├── App.js
│ │ ├── SelectIcon.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── slider
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── splitter
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── tabs
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── tags-input
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ ├── toast
│ │ ├── App.js
│ │ ├── CloseIcon.js
│ │ ├── index.ts
│ │ └── styles.css
│ │ └── tooltip
│ │ ├── App.js
│ │ ├── index.ts
│ │ └── styles.css
├── solid
│ ├── shared
│ │ ├── 404
│ │ │ └── index.ts
│ │ └── wrapper
│ │ │ ├── index.html
│ │ │ ├── index.ts
│ │ │ └── vite.config.js
│ ├── tailwind
│ │ └── inline
│ │ │ └── checkbox
│ │ │ └── index.ts
│ └── vanilla_css
│ │ └── scoped
│ │ ├── accordion
│ │ ├── AccordionIcon.js
│ │ ├── App.js
│ │ └── index.ts
│ │ └── checkbox
│ │ ├── App.js
│ │ ├── CheckIcon.js
│ │ ├── MinusIcon.js
│ │ └── index.ts
├── utils.ts
└── vue
│ ├── shared
│ ├── 404
│ │ └── index.ts
│ └── wrapper
│ │ └── index.ts
│ ├── tailwind
│ └── inline
│ │ └── checkbox
│ │ └── index.ts
│ └── vanilla_css
│ └── scoped
│ ├── checkbox
│ ├── App.vue
│ ├── CheckIcon.vue
│ ├── MinusIcon.vue
│ └── index.ts
│ ├── popover
│ ├── App.vue
│ └── index.ts
│ └── select
│ ├── App.vue
│ ├── SelectIcon.vue
│ └── index.ts
├── components
├── CloseButton.tsx
├── CodeEditor.tsx
├── ColorModeButton.tsx
├── ColorModeScript.tsx
├── ComponentControls
│ ├── FrameworkSwitch.tsx
│ ├── Navigation
│ │ ├── Search.tsx
│ │ └── index.tsx
│ ├── StyleSolutionSwitch.tsx
│ ├── StyleTypeSwitch.tsx
│ └── index.tsx
├── CopyCodeButton.tsx
├── EditorTabs.tsx
├── FormatCodeButton.tsx
├── IconButton.tsx
├── LinkOverlay.tsx
├── Navbar.tsx
├── OpenInCodesandboxButton.tsx
├── SelectIcon.tsx
├── button.tsx
└── card.tsx
├── index.css
├── next.config.js
├── package.json
├── panda.config.ts
├── pnpm-lock.yaml
├── postcss.config.js
├── theme
├── global-css.ts
├── recipes
│ ├── button.ts
│ ├── dialog.ts
│ ├── index.ts
│ ├── input.ts
│ ├── select.ts
│ └── splitter.ts
└── text-styles.ts
├── tsconfig.json
└── utils
├── component-config
├── constants.ts
└── index.ts
├── component-setup
├── constants.ts
└── index.ts
├── types.ts
├── useColorMode.ts
├── useComponentConfig.ts
├── useComponentSetup.ts
├── useComponentsSearch.ts
└── useSyncSandboxColorMode.ts
/.eslintignore:
--------------------------------------------------------------------------------
1 | component-data
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | ## Panda
39 | design-system
40 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .next
2 | .vscode
3 | .eslintrc.json
4 | next-env.d.ts
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth": 2,
3 | "trailingComma": "es5",
4 | "singleQuote": false,
5 | "semi": true,
6 |
7 | "plugins": ["@trivago/prettier-plugin-sort-imports"],
8 | "importOrder": [
9 | "^design-system/(.*)$",
10 | "^components/(.*)$",
11 | "^utils/(.*)$",
12 | "^[./]"
13 | ],
14 | "importOrderSeparation": true,
15 | "importOrderSortSpecifiers": true
16 | }
17 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules/.pnpm/typescript@5.0.2/node_modules/typescript/lib",
3 | "typescript.enablePromptUseWorkspaceTsdk": true
4 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Arkxamples
2 |
3 | Sandbox to view [Ark UI](https://github.com/chakra-ui/ark) styling examples.
4 |
5 | Built with [CSS panda](), [Sandpack](sandpack.codesandbox.io/) and ❤️
6 |
7 | ## Contribution
8 |
9 | Feel free to open a pull request for any of the unchecked components. The only requirement, is that it matches the **Vanilla CSS** version. By match, i mean _Look like it_ 😉
10 |
11 | ## State
12 |
13 | ### Vanilla CSS
14 |
15 | | Scoped | React | Vue | Solid |
16 | | ------------ | ----- | --- | ----- |
17 | | Accordion | 🟢 | ⚪ | 🟢 |
18 | | Carousel | ⚪ | ⚪ | ⚪ |
19 | | Checkbox | 🟢 | 🟢 | 🟢 |
20 | | Dialog | 🟢 | ⚪ | ⚪ |
21 | | Combobox | ⚪ | ⚪ | ⚪ |
22 | | Editable | ⚪ | ⚪ | ⚪ |
23 | | Hover Card | 🟢 | ⚪ | ⚪ |
24 | | Menu | 🟢 | ⚪ | ⚪ |
25 | | Number Input | 🟢 | ⚪ | ⚪ |
26 | | Pagination | 🟢 | ⚪ | ⚪ |
27 | | Pin Input | 🟢 | ⚪ | ⚪ |
28 | | Popover | 🟢 | 🟢 | ⚪ |
29 | | Radio Group | 🟢 | ⚪ | ⚪ |
30 | | Range Slider | 🟢 | ⚪ | ⚪ |
31 | | Rating | 🟢 | ⚪ | ⚪ |
32 | | Select | 🟢 | 🟢 | ⚪ |
33 | | Slider | 🟢 | ⚪ | ⚪ |
34 | | Splitter | 🟢 | ⚪ | ⚪ |
35 | | Tabs | 🟢 | ⚪ | ⚪ |
36 | | Tags Input | 🟢 | ⚪ | ⚪ |
37 | | Toast | 🟢 | ⚪ | ⚪ |
38 | | Tooltip | 🟢 | ⚪ | ⚪ |
39 |
40 | ### Tailwind
41 |
42 | | Inline | React | Vue | Solid |
43 | | ------------ | ----- | --- | ----- |
44 | | Accordion | ⚪ | ⚪ | ⚪ |
45 | | Carousel | ⚪ | ⚪ | ⚪ |
46 | | Checkbox | 🟢 | 🟢 | 🟢 |
47 | | Dialog | ⚪ | ⚪ | ⚪ |
48 | | Combobox | ⚪ | ⚪ | ⚪ |
49 | | Editable | ⚪ | ⚪ | ⚪ |
50 | | Hover Card | ⚪ | ⚪ | ⚪ |
51 | | Menu | ⚪ | ⚪ | ⚪ |
52 | | Number Input | ⚪ | ⚪ | ⚪ |
53 | | Pagination | ⚪ | ⚪ | ⚪ |
54 | | Pin Input | ⚪ | ⚪ | ⚪ |
55 | | Popover | ⚪ | ⚪ | ⚪ |
56 | | Radio Group | ⚪ | ⚪ | ⚪ |
57 | | Range Slider | ⚪ | ⚪ | ⚪ |
58 | | Rating | ⚪ | ⚪ | ⚪ |
59 | | Select | ⚪ | ⚪ | ⚪ |
60 | | Slider | ⚪ | ⚪ | ⚪ |
61 | | Splitter | ⚪ | ⚪ | ⚪ |
62 | | Tabs | ⚪ | ⚪ | ⚪ |
63 | | Tags Input | ⚪ | ⚪ | ⚪ |
64 | | Toast | ⚪ | ⚪ | ⚪ |
65 | | Tooltip | ⚪ | ⚪ | ⚪ |
66 |
67 |
93 |
--------------------------------------------------------------------------------
/app/[component]/layout.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { SandpackLayout, SandpackProvider } from "@codesandbox/sandpack-react";
4 | import { PropsWithChildren } from "react";
5 |
6 | import { formatFiles } from "utils/component-setup";
7 | import { getArkPackage, templates } from "utils/component-setup/constants";
8 | import { ComponentId } from "utils/types";
9 | import { useColorMode } from "utils/useColorMode";
10 | import { useComponentConfig } from "utils/useComponentConfig";
11 | import { useComponentSetup } from "utils/useComponentSetup";
12 |
13 | const ComponentLayout = (
14 | props: PropsWithChildren & { params: { component: ComponentId } }
15 | ) => {
16 | const { component: componentId } = props.params;
17 |
18 | const { colorMode } = useColorMode();
19 |
20 | const componentDetails = useComponentSetup(componentId);
21 |
22 | const componentConfig = useComponentConfig();
23 |
24 | if (!componentConfig) return "Loading...";
25 |
26 | const { framework, styleSolution } = componentConfig;
27 |
28 | return (
29 |
46 | {props.children}
47 |
48 | );
49 | };
50 |
51 | export default ComponentLayout;
52 |
--------------------------------------------------------------------------------
/app/[component]/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { Splitter, SplitterPanel, SplitterResizeTrigger } from "@ark-ui/react";
4 | import { SandpackPreview } from "@codesandbox/sandpack-react";
5 |
6 | import { css, cx } from "design-system/css";
7 | import { panda } from "design-system/jsx";
8 | import { splitter } from "design-system/recipes";
9 |
10 | import { CodeEditor } from "components/CodeEditor";
11 | import { ComponentControls } from "components/ComponentControls";
12 | import { Navbar } from "components/Navbar";
13 |
14 | import { getComponent } from "utils/component-setup";
15 | import { ComponentParams } from "utils/types";
16 | import { useSyncSandboxColorMode } from "utils/useSyncSandboxColorMode";
17 |
18 | export default function Component(props: { params: ComponentParams }) {
19 | const { component: componentId } = props.params;
20 | const component = getComponent(componentId as any);
21 |
22 | useSyncSandboxColorMode();
23 |
24 | return (
25 | <>
26 |
42 |
43 |
47 |
48 |
49 |
55 |
56 |
63 |
64 |
65 |
66 |
67 |
68 | >
69 | );
70 | }
71 |
--------------------------------------------------------------------------------
/app/layout.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cx } from "@/panda/css";
4 | import { getSandpackCssText } from "@codesandbox/sandpack-react";
5 | import { Fira_Code, Inter } from "next/font/google";
6 | import type { PropsWithChildren } from "react";
7 |
8 | // import "design-system/styles.css";
9 | import { ColorModeScript } from "components/ColorModeScript";
10 |
11 | import "../index.css";
12 |
13 | const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
14 | const firaCode = Fira_Code({
15 | subsets: ["latin"],
16 | variable: "--font-fira-code",
17 | });
18 |
19 | const RootLayout = (props: PropsWithChildren) => {
20 | return (
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 | {props.children}
33 |
34 | );
35 | };
36 |
37 | export default RootLayout;
38 |
--------------------------------------------------------------------------------
/app/page.tsx:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return (
3 |
4 |
5 | Don't have an idea for the homepage yet. Let's just get to the
6 | actual thing:
7 |
8 |
Get started
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/component-data/react/shared/404/App.js:
--------------------------------------------------------------------------------
1 | import "./styles.css";
2 |
3 | export default function App() {
4 | return (
5 |
6 |
No example for this yet.
7 | Feel free to contribute
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/component-data/react/shared/404/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/shared/404/styles.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anubra266/arkxamples/b6e7c4f643559834ece6ccab5e9cd2ecfd5f08e9/component-data/react/shared/404/styles.css
--------------------------------------------------------------------------------
/component-data/react/shared/wrapper/index.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;700&display=swap");
2 |
3 | #root {
4 | max-width: 1280px;
5 | margin: 0 auto;
6 | padding: 2rem;
7 | }
8 |
9 | #root > *:first-child {
10 | max-width: calc(100vw - 4rem);
11 | }
12 |
13 | body {
14 | margin: 0;
15 | display: flex;
16 | place-items: center;
17 | min-width: 320px;
18 | min-height: 100vh;
19 | font-family: "Poppins", sans-serif;
20 | background-color: #ffff;
21 | color: black;
22 | color-scheme: light;
23 | }
24 |
25 | body.dark {
26 | background-color: #111;
27 | color: white;
28 | color-scheme: dark;
29 | }
30 |
31 | a {
32 | text-decoration: none;
33 | }
34 |
35 | svg {
36 | max-width: unset;
37 | }
38 |
--------------------------------------------------------------------------------
/component-data/react/shared/wrapper/index.ts:
--------------------------------------------------------------------------------
1 | export const sharedReactCode = {
2 | "/index.css": require("!!raw-loader!./index.css").default,
3 |
4 | "/index.js": /*javascript*/ `
5 | import React, { StrictMode } from "react";
6 | import { createRoot } from "react-dom/client";
7 | import { Helmet } from "react-helmet";
8 | import "./index.css";
9 |
10 | import App from "./App";
11 |
12 | function ColorModeScript() {
13 | React.useEffect(() => {
14 | window.parent.postMessage({ action: "getColorMode" }, "*");
15 | window.addEventListener("message", function (event) {
16 | if (event.data.colorMode) {
17 | switch (event.data.colorMode) {
18 | case "light":
19 | document.body.classList.add("light");
20 | document.body.classList.remove("dark");
21 | break;
22 |
23 | case "dark":
24 | document.body.classList.add("dark");
25 | document.body.classList.remove("light");
26 | break;
27 |
28 | default:
29 | break;
30 | }
31 | }
32 | });
33 | }, []);
34 | return (
35 |
36 |
40 |
47 |
48 | );
49 | }
50 |
51 | const root = createRoot(document.getElementById("root"));
52 | root.render(
53 |
54 |
55 |
56 |
57 | );
58 |
59 | `,
60 | };
61 |
--------------------------------------------------------------------------------
/component-data/react/tailwind/inline/checkbox/index.ts:
--------------------------------------------------------------------------------
1 | import { styles } from "component-data/react/tailwind/inline/checkbox/styles";
2 | import { checkbox } from "component-data/react/vanilla_css/scoped/checkbox";
3 | import { tailwindInlineTransform } from "component-data/utils";
4 |
5 | export default tailwindInlineTransform(checkbox, styles);
6 |
--------------------------------------------------------------------------------
/component-data/react/tailwind/inline/checkbox/styles.ts:
--------------------------------------------------------------------------------
1 | export const styles = {
2 | rootStyles: `"flex items-center cursor-pointer gap-2 mt-3 /*You don't need this, just here to move the child checkboxes to the right */ [&~div:not([data-scope='checkbox'])]:ml-3"`,
3 | labelStyles: `"inline-flex flex-column gap-0.5"`,
4 | inputStyles: null,
5 | controlStyles: `"items-center bg-[#fafaf9] border-[#d7d3d0] rounded-md border border-solid flex h-[30px] w-[30px] justify-center dark:bg-[#141313] dark:border-[#3e3e3e] data-[focus]:shadow-[0_0_0_4px_#ede9fe] dark:data-[focus]:shadow-[0_0_0_4px_#292524] data-[hover]:border-[#a9a29d] dark:data-[hover]:border-[#44403c] data-[checked]:bg-[#60a5fa] data-[checked]:border-[#60a5fa] data-[checked]:text-white dark:data-[checked]:bg-[#60a5fa] dark:data-[checked]:border-[#60a5fa] dark:data-[checked]:text-black data-[indeterminate]:border-[#60a5fa] data-[indeterminate]:text-[#60a5fa]"`,
6 | };
7 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/accordion/AccordionIcon.js:
--------------------------------------------------------------------------------
1 | export default function AccordionIcon(props) {
2 | const iconStyles = {
3 | transform: props.isOpen ? "rotate(-180deg)" : undefined,
4 | transition: "transform 0.2s",
5 | transformOrigin: "center",
6 | };
7 | return (
8 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/accordion/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Accordion,
3 | AccordionContent,
4 | AccordionItem,
5 | AccordionTrigger,
6 | } from "@ark-ui/react";
7 |
8 | import AccordionIcon from "./AccordionIcon";
9 | import "./styles.css";
10 |
11 | const items = ["React", "Solid", "Vue"];
12 |
13 | export default function Page() {
14 | return (
15 |
16 | {items.map((item, id) => (
17 |
18 | {({ isOpen }) => (
19 | <>
20 |
21 |
25 |
26 |
27 | Pudding donut gummies chupa chups oat cake marzipan biscuit
28 | tart. Dessert macaroon ice cream bonbon jelly. Jelly topping
29 | tiramisu halvah lollipop.
30 |
31 | >
32 | )}
33 |
34 | ))}
35 |
36 | );
37 | }
38 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/accordion/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | "/AccordionIcon.js": require("./AccordionIcon.js").default,
8 | ...sharedReactCode,
9 | },
10 | visibleFiles: ["/App.js", "/styles.css", "/AccordionIcon.js"],
11 | };
12 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/accordion/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="accordion"][data-part="root"] {
2 | --border-default: #e7e5e4;
3 | display: flex;
4 | flex-direction: column;
5 | background: #fafaf9;
6 | padding: 24px;
7 | border-radius: 0.5rem;
8 | border: solid 1px;
9 | border-color: var(--border-default);
10 | width: 40rem;
11 | }
12 |
13 | .dark [data-scope="accordion"][data-part="root"] {
14 | --border-default: #3e3e3e;
15 | }
16 |
17 | [data-scope="accordion"][data-part="root"] > :not([hidden]) ~ :not([hidden]) {
18 | border-top: solid 1px;
19 | border-bottom: solid 0px;
20 | border-top-color: var(--border-default);
21 | }
22 |
23 | .dark [data-scope="accordion"][data-part="root"] {
24 | background: #1b1a1a;
25 | }
26 |
27 | [data-scope="accordion"][data-part="trigger"] {
28 | all: unset;
29 | display: flex;
30 | align-items: center;
31 | background: transparent;
32 | border-radius: 0.5rem;
33 | cursor: pointer;
34 | font-weight: 500;
35 | justify-content: space-between;
36 | padding: 0;
37 | padding-bottom: 16px;
38 | font-size: 1rem;
39 | line-height: 1.5rem;
40 | width: 100%;
41 | color: #0d0d0d;
42 | }
43 |
44 | [data-scope="accordion"][data-part="trigger"]:not([data-expanded]) {
45 | padding-bottom: 8px;
46 | }
47 |
48 | .dark [data-scope="accordion"][data-part="trigger"] {
49 | color: white;
50 | }
51 |
52 | [data-scope="accordion"][data-part="item"]:not([hidden])
53 | ~ :not([hidden])
54 | > [data-part="trigger"] {
55 | padding-top: 16px;
56 | }
57 |
58 | [data-scope="accordion"][data-part="content"] {
59 | padding-bottom: 16px;
60 | padding-right: 48px;
61 | font-size: 0.875rem;
62 | line-height: 1.25rem;
63 | color: #737373;
64 | }
65 | .dark [data-scope="accordion"][data-part="content"] {
66 | color: #8c8c8c;
67 | }
68 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/checkbox/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Checkbox,
3 | CheckboxControl,
4 | CheckboxInput,
5 | CheckboxLabel,
6 | } from "@ark-ui/react";
7 | import React from "react";
8 |
9 | import CheckIcon from "./CheckIcon";
10 | import MinusIcon from "./MinusIcon";
11 | import "./styles.css";
12 |
13 | export default function Page() {
14 | const [checkedItems, setCheckedItems] = React.useState([false, false]);
15 |
16 | const allChecked = checkedItems.every(Boolean);
17 | const someChecked = checkedItems.some(Boolean) && !allChecked;
18 |
19 | return (
20 | <>
21 |
26 | setCheckedItems([e.checked === true, e.checked === true])
27 | }
28 | >
29 | {(state) => (
30 | <>
31 |
32 |
33 | {state.isChecked && }
34 | {state.isIndeterminate && }
35 |
36 |
37 | Parent Checkbox
38 |
39 | >
40 | )}
41 |
42 |
43 |
47 | setCheckedItems([e.checked === true, checkedItems[1]])
48 | }
49 | >
50 | {(state) => (
51 | <>
52 |
53 |
54 | {state.isChecked && }
55 |
56 |
57 | Child Checkbox 1
58 |
59 | >
60 | )}
61 |
62 |
66 | setCheckedItems([checkedItems[0], e.checked === true])
67 | }
68 | >
69 | {(state) => (
70 | <>
71 |
72 |
73 | {state.isChecked && }
74 |
75 |
76 | Child Checkbox 2
77 |
78 | >
79 | )}
80 |
81 |
82 | >
83 | );
84 | }
85 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/checkbox/CheckIcon.js:
--------------------------------------------------------------------------------
1 | export default function CheckIcon() {
2 | return (
3 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/checkbox/MinusIcon.js:
--------------------------------------------------------------------------------
1 | export default function MinusIcon() {
2 | return (
3 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/checkbox/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 | import { vanillaScopedTransform } from "component-data/utils";
3 |
4 | export const checkbox = {
5 | files: {
6 | "/styles.css": require("!!raw-loader!./styles.css").default,
7 | "/App.js": require("./App.js").default,
8 | "/CheckIcon.js": require("./CheckIcon.js").default,
9 | "/MinusIcon.js": require("./MinusIcon.js").default,
10 | ...sharedReactCode,
11 | },
12 | visibleFiles: ["/App.js", "/styles.css", "/CheckIcon.js", "/MinusIcon.js"],
13 | };
14 | export default vanillaScopedTransform(checkbox);
15 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/checkbox/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="checkbox"][data-part="root"] {
2 | display: flex;
3 | align-items: center;
4 | cursor: pointer;
5 | gap: 8px;
6 | --accent-default: #60a5fa;
7 | /* You don't need this */
8 | margin-top: 12px;
9 | }
10 |
11 | [data-scope="checkbox"][data-part="label"] {
12 | display: inline-flex;
13 | flex-direction: column;
14 | gap: 2px;
15 | }
16 |
17 | [data-scope="checkbox"][data-part="control"] {
18 | align-items: center;
19 | background: #fafaf9;
20 | border-color: #d7d3d0;
21 | border-radius: 0.375rem;
22 | border-width: 1px;
23 | border-style: solid;
24 | display: flex;
25 | height: 30px;
26 | width: 30px;
27 | justify-content: center;
28 | }
29 |
30 | .dark [data-scope="checkbox"][data-part="control"] {
31 | background: #141313;
32 | border-color: #3e3e3e;
33 | }
34 |
35 | [data-scope="checkbox"][data-part="control"][data-focus] {
36 | box-shadow: 0 0 0 4px #ede9fe;
37 | }
38 |
39 | .dark [data-scope="checkbox"][data-part="control"][data-focus] {
40 | box-shadow: 0 0 0 4px #292524;
41 | }
42 |
43 | [data-scope="checkbox"][data-part="control"][data-hover] {
44 | border-color: #a9a29d;
45 | }
46 |
47 | .dark [data-scope="checkbox"][data-part="control"][data-hover] {
48 | border-color: #44403c;
49 | }
50 |
51 | [data-scope="checkbox"][data-part="control"][data-checked] {
52 | background-color: var(--accent-default);
53 | border-color: var(--accent-default);
54 | color: white;
55 | }
56 |
57 | .dark [data-scope="checkbox"][data-part="control"][data-checked] {
58 | color: black;
59 | }
60 |
61 | [data-scope="checkbox"][data-part="control"][data-indeterminate] {
62 | border-color: var(--accent-default);
63 | color: var(--accent-default);
64 | }
65 |
66 | /* You don't need this, just here to move the child checkboxes to the right */
67 | [data-scope="checkbox"][data-part="root"] ~ div:not([data-scope="checkbox"]) {
68 | margin-left: 12px;
69 | }
70 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/dialog/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Dialog,
3 | DialogBackdrop,
4 | DialogCloseTrigger,
5 | DialogContainer,
6 | DialogContent,
7 | DialogDescription,
8 | DialogTitle,
9 | DialogTrigger,
10 | Portal,
11 | } from "@ark-ui/react";
12 |
13 | import CloseIcon from "./CloseIcon";
14 | import "./styles.css";
15 |
16 | export default function Page() {
17 | return (
18 |
56 | );
57 | }
58 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/dialog/CloseIcon.js:
--------------------------------------------------------------------------------
1 | export default function CloseIcon() {
2 | return (
3 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/dialog/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | "/CloseIcon.js": require("./CloseIcon.js").default,
8 | ...sharedReactCode,
9 | },
10 | visibleFiles: ["/App.js", "/styles.css", "/CloseIcon.js"],
11 | };
12 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/dialog/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="dialog"][data-part="backdrop"] {
2 | opacity: 0.7;
3 | inset: 0;
4 | position: fixed;
5 | z-index: 200;
6 | background: #404040;
7 | }
8 |
9 | .dark [data-scope="dialog"][data-part="backdrop"] {
10 | background: black;
11 | }
12 |
13 | [data-scope="dialog"][data-part="container"] {
14 | display: flex;
15 | align-items: center;
16 | justify-content: center;
17 | position: fixed;
18 | inset: 0;
19 | z-index: 200;
20 | }
21 |
22 | [data-scope="dialog"][data-part="content"] {
23 | position: relative;
24 | min-width: 24rem;
25 | border-radius: 0.75rem;
26 | background: white;
27 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
28 | 0px 8px 16px rgba(48, 49, 51, 0.1);
29 | }
30 |
31 | .dark [data-scope="dialog"][data-part="content"] {
32 | background: #191919;
33 | box-shadow: 0px 0px 1px #0d0d0d, 0px 8px 16px rgba(13, 13, 13, 0.9);
34 | }
35 |
36 | [data-scope="dialog"][data-part="title"] {
37 | font-weight: 600;
38 | line-height: 1.75rem;
39 | font-size: 1.125rem;
40 | }
41 |
42 | [data-scope="dialog"][data-part="description"] {
43 | line-height: 1.25rem;
44 | font-size: 0.875rem;
45 | color: #737373;
46 | }
47 |
48 | .dark [data-scope="dialog"][data-part="description"] {
49 | color: #8c8c8c;
50 | }
51 |
52 | .stack {
53 | display: flex;
54 | flex-direction: column;
55 | }
56 |
57 | .content {
58 | gap: 32px;
59 | padding: 24px;
60 | }
61 |
62 | .header {
63 | gap: 4px;
64 | }
65 |
66 | .button {
67 | all: unset;
68 | align-items: center;
69 | appearance: none;
70 | border-radius: 0.5rem;
71 | cursor: pointer;
72 | display: inline-flex;
73 | font-weight: 500;
74 | justify-content: center;
75 | outline: none;
76 | position: relative;
77 | transition-property: color, background-color, border-color, outline-color,
78 | text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
79 | backdrop-filter;
80 | transition-duration: 100ms;
81 | transition-timing-function: ease-out;
82 | user-select: none;
83 | vertical-align: middle;
84 | white-space: nowrap;
85 |
86 | --fg-emphasized: #404040;
87 | --fg-default: #0d0d0d;
88 | --bg-subtle: #d9d9d9;
89 | }
90 |
91 | .dark .button {
92 | --fg-emphasized: #bfbfbf;
93 | --fg-default: white;
94 | --bg-subtle: #262626;
95 | }
96 |
97 | .button_size__md {
98 | height: 40px;
99 | min-width: 40px;
100 | padding-inline: 16px;
101 | line-height: 1.25rem;
102 | font-size: 0.875rem;
103 | }
104 |
105 | .w_full {
106 | width: 100%;
107 | }
108 |
109 | .actions {
110 | gap: 12px;
111 | flex-direction: row;
112 | width: 100%;
113 | }
114 |
115 | .button_primary {
116 | color: white;
117 | background-color: #60a5fa;
118 | }
119 |
120 | .button_primary:hover {
121 | background-color: #3b82f6;
122 | }
123 |
124 | .button_primary:focus {
125 | z-index: 1;
126 | --shadow: #eff6ff;
127 | box-shadow: 0 0 0 4px var(--shadow);
128 | }
129 |
130 | .dark .button_primary:focus {
131 | --shadow: #404040;
132 | }
133 |
134 | .button_secondary {
135 | border: solid 1px;
136 | background: white;
137 | border-color: #a6a6a6;
138 | color: #404040;
139 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
140 | 0px 1px 2px rgba(48, 49, 51, 0.1);
141 | }
142 |
143 | .button_secondary:focus {
144 | z-index: 1;
145 | box-shadow: 0 0 0 4px #d9d9d9;
146 | }
147 | .dark .button_secondary {
148 | background: #191919;
149 | border-color: #262626;
150 | color: #bfbfbf;
151 | box-shadow: 0px 0px 1px #0d0d0d, 0px 1px 2px rgba(13, 13, 13, 0.9);
152 | }
153 |
154 | .dark .button_secondary:focus {
155 | box-shadow: 0 0 0 4px #262626;
156 | }
157 |
158 | .button_secondary:hover {
159 | color: var(--fg-default);
160 | background: var(--bg-subtle);
161 | }
162 |
163 | .button_tertiary {
164 | padding-inline: 0px;
165 | background: transparent;
166 | color: #404040;
167 | }
168 |
169 | .button_tertiary:focus {
170 | z-index: 1;
171 | --shadow: #d9d9d9;
172 | box-shadow: 0 0 0 4px var(--shadow);
173 | }
174 |
175 | .dark .button_tertiary:focus {
176 | --shadow: #262626;
177 | }
178 |
179 | .button_tertiary:hover {
180 | color: var(--fg-default);
181 | background: var(--bg-subtle);
182 | }
183 |
184 | .dark .button_tertiary {
185 | color: #737373;
186 | }
187 |
188 | .close_button {
189 | position: absolute;
190 | top: 16px;
191 | right: 16px;
192 | color: #8c8c8c;
193 | }
194 |
195 | .close_button svg {
196 | font-size: 1.25rem;
197 | display: inline-flex;
198 | align-self: center;
199 | flex-shrink: 0;
200 | }
201 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/hover-card/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | HoverCard,
3 | HoverCardArrow,
4 | HoverCardArrowTip,
5 | HoverCardContent,
6 | HoverCardPositioner,
7 | HoverCardTrigger,
8 | Portal,
9 | } from "@ark-ui/react";
10 |
11 | import MapPinIcon from "./MapPinIcon";
12 | import "./styles.css";
13 |
14 | export default function Page() {
15 | return (
16 |
17 |
18 |
23 |
24 |

28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |

44 |
45 |
46 |
52 |
53 |
54 |
55 |
56 | segunadebayo
57 | Segun Adebayo
58 |
59 |
60 | Building @chakra-ui ⚡️. Design Systems and UI Engineer
61 |
62 |
63 |
64 |
65 |
Dubai, United Arab Emirates
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | );
74 | }
75 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/hover-card/MapPinIcon.js:
--------------------------------------------------------------------------------
1 | export default function MapPinIcon() {
2 | return (
3 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/hover-card/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | "/MapPinIcon.js": require("./MapPinIcon.js").default,
8 | ...sharedReactCode,
9 | },
10 | visibleFiles: ["/App.js", "/styles.css", "/MapPinIcon.js"],
11 | };
12 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/hover-card/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="hover-card"][data-part="positioner"] {
2 | --hover-card-background: #fafaf9;
3 | --border-default: #e7e5e4;
4 | background: var(--hover-card-background);
5 | border: solid 1px;
6 | border-color: var(--border-default);
7 | border-radius: 0.5rem;
8 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
9 | 0px 16px 24px rgba(48, 49, 51, 0.1);
10 | }
11 |
12 | .dark [data-scope="hover-card"][data-part="positioner"] {
13 | --hover-card-background: #3e3e3e;
14 | --border-default: #3e3e3e;
15 | box-shadow: 0px 0px 1px #0d0d0d, 0px 16px 24px rgba(13, 13, 13, 0.9);
16 | }
17 |
18 | [data-scope="hover-card"][data-part="content"] {
19 | position: relative;
20 | padding: 16px;
21 | max-width: 20rem;
22 | }
23 |
24 | [data-scope="hover-card"][data-part="arrow"] {
25 | /* This variables are consumed by ark ui */
26 | --arrow-size: 12px;
27 | --arrow-background: var(--hover-card-background);
28 | }
29 |
30 | [data-scope="hover-card"][data-part="arrow-tip"] {
31 | border-top: solid 1px;
32 | border-left: solid 1px;
33 | border-color: var(--border-default);
34 | }
35 |
36 | .avatar {
37 | border-radius: 9999px;
38 | position: relative;
39 | overflow: hidden;
40 | background: #a6a6a6;
41 | }
42 |
43 | .avatar_size__lg {
44 | height: 48px;
45 | width: 48px;
46 | }
47 |
48 | .avatar_size__sm {
49 | height: 40px;
50 | width: 40px;
51 | }
52 |
53 | .dark .avatar {
54 | background: #404040;
55 | }
56 |
57 | .avatar img {
58 | position: absolute;
59 | inset: 0;
60 | height: 100%;
61 | width: 100%;
62 | }
63 |
64 | .fg_muted {
65 | color: #737373;
66 | }
67 |
68 | .dark .fg_muted {
69 | color: #8c8c8c;
70 | }
71 |
72 | .fg_subtle {
73 | color: #8c8c8c;
74 | }
75 |
76 | .dark .fg_subtle {
77 | color: #737373;
78 | }
79 |
80 | .stack {
81 | display: flex;
82 | flex-direction: column;
83 | gap: 4px;
84 | }
85 |
86 | .align_center {
87 | align-items: center;
88 | }
89 |
90 | .row {
91 | flex-direction: row;
92 | }
93 |
94 | .header {
95 | gap: 8px;
96 | width: 100%;
97 | justify-content: space-between;
98 | }
99 |
100 | .content {
101 | gap: 16px;
102 | }
103 |
104 | .body {
105 | gap: 8px;
106 | }
107 |
108 | .text_xs {
109 | font-size: 0.75rem;
110 | line-height: 1.125rem;
111 | }
112 |
113 | .text_sm {
114 | font-size: 0.875rem;
115 | line-height: 1.25rem;
116 | }
117 |
118 | .text_semibold {
119 | font-weight: 500;
120 | }
121 |
122 | .button {
123 | all: unset;
124 | align-items: center;
125 | appearance: none;
126 | border-radius: 0.5rem;
127 | cursor: pointer;
128 | display: inline-flex;
129 | font-weight: 500;
130 | justify-content: center;
131 | outline: none;
132 | position: relative;
133 | transition-property: color, background-color, border-color, outline-color,
134 | text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
135 | backdrop-filter;
136 | transition-duration: 100ms;
137 | transition-timing-function: ease-out;
138 | user-select: none;
139 | vertical-align: middle;
140 | white-space: nowrap;
141 |
142 | --fg-default: #0d0d0d;
143 | --bg-subtle: #d9d9d9;
144 | }
145 |
146 | .dark .button {
147 | --fg-default: white;
148 | --bg-subtle: #262626;
149 | }
150 |
151 | .button_size__xs {
152 | height: 32px;
153 | min-width: 32px;
154 | padding-inline: 12px;
155 | }
156 |
157 | .button_secondary {
158 | border: solid 1px;
159 | background: white;
160 | border-color: #a6a6a6;
161 | color: #404040;
162 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
163 | 0px 1px 2px rgba(48, 49, 51, 0.1);
164 | }
165 |
166 | .button_secondary:focus {
167 | z-index: 1;
168 | box-shadow: 0 0 0 4px #d9d9d9;
169 | }
170 | .dark .button_secondary {
171 | background: #191919;
172 | border-color: #262626;
173 | color: #bfbfbf;
174 | box-shadow: 0px 0px 1px #0d0d0d, 0px 1px 2px rgba(13, 13, 13, 0.9);
175 | }
176 |
177 | .dark .button_secondary:focus {
178 | box-shadow: 0 0 0 4px #262626;
179 | }
180 |
181 | .button_secondary:hover {
182 | color: var(--fg-default);
183 | background: var(--bg-subtle);
184 | }
185 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/menu/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Menu,
3 | MenuContent,
4 | MenuItem,
5 | MenuItemGroup,
6 | MenuItemGroupLabel,
7 | MenuPositioner,
8 | MenuSeparator,
9 | MenuTrigger,
10 | MenuTriggerItem,
11 | Portal,
12 | } from "@ark-ui/react";
13 |
14 | import RightIcon from "./RightIcon";
15 | import "./styles.css";
16 |
17 | export default function Page() {
18 | return (
19 |
70 | );
71 | }
72 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/menu/RightIcon.js:
--------------------------------------------------------------------------------
1 | export default function RightIcon() {
2 | return (
3 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/menu/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | "/RightIcon.js": require("./RightIcon.js").default,
8 | ...sharedReactCode,
9 | },
10 | visibleFiles: ["/App.js", "/styles.css", "/RightIcon.js"],
11 | };
12 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/menu/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="menu"][data-part="positioner"] {
2 | z-index: 100;
3 | --border-default: #e7e5e4;
4 | --fg-emphasized: #404040;
5 | --bg-subtle: #d9d9d91e;
6 | }
7 |
8 | .dark [data-scope="menu"][data-part="positioner"] {
9 | --border-default: #3e3e3e;
10 | --fg-emphasized: #c1c1c1;
11 | --bg-subtle: #3333335e;
12 | }
13 |
14 | [data-scope="menu"][data-part="separator"] {
15 | /* In some browsers, hr has borders on all sides by default, we only want a bottom border */
16 | border: none;
17 | border-bottom: solid 1px;
18 | border-color: var(--border-default);
19 | margin-block: 4px;
20 | }
21 |
22 | [data-scope="menu"][data-part="content"] {
23 | background: #fafaf9;
24 | outline: none;
25 | padding-inline: 6px;
26 | padding-block: 2px;
27 | min-width: 15rem;
28 | border: solid 1px;
29 | border-color: var(--border-default);
30 | border-radius: 0.5rem;
31 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
32 | 0px 8px 16px rgba(48, 49, 51, 0.1);
33 | }
34 |
35 | .dark [data-scope="menu"][data-part="content"] {
36 | background: #1b1a1a;
37 | box-shadow: 0px 0px 1px #0d0d0d, 0px 8px 16px rgba(13, 13, 13, 0.9);
38 | }
39 |
40 | [data-scope="menu"][data-part="item-group-label"] {
41 | font-weight: 600;
42 | padding-inline: 10px;
43 | padding-block: 12px;
44 | font-size: 0.875rem;
45 | line-height: 1.25rem;
46 | }
47 |
48 | [data-scope="menu"][data-part="item"],
49 | [data-scope="menu"][data-part="trigger-item"] {
50 | display: flex;
51 | align-items: center;
52 | border-radius: 0.375rem;
53 | cursor: pointer;
54 | margin-block: 4px;
55 | font-size: 0.875rem;
56 | line-height: 1.25rem;
57 | padding-inline: 10px;
58 | padding-block: 8px;
59 | color: var(--fg-emphasized);
60 | }
61 |
62 | [data-scope="menu"][data-part="item"][data-focus],
63 | [data-scope="menu"][data-part="trigger-item"][data-focus] {
64 | background: var(--bg-subtle);
65 | }
66 |
67 | .flex_1 {
68 | flex: 1;
69 | }
70 |
71 | .button {
72 | all: unset;
73 | align-items: center;
74 | appearance: none;
75 | border-radius: 0.5rem;
76 | cursor: pointer;
77 | display: inline-flex;
78 | font-weight: 500;
79 | justify-content: center;
80 | outline: none;
81 | position: relative;
82 | transition-property: color, background-color, border-color, outline-color,
83 | text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
84 | backdrop-filter;
85 | transition-duration: 100ms;
86 | transition-timing-function: ease-out;
87 | user-select: none;
88 | vertical-align: middle;
89 | white-space: nowrap;
90 | }
91 |
92 | .button_primary {
93 | color: white;
94 | background-color: #60a5fa;
95 | }
96 |
97 | .button_primary:hover {
98 | background-color: #3b82f6;
99 | }
100 |
101 | .button_primary:focus {
102 | z-index: 1;
103 | --shadow: #eff6ff;
104 | box-shadow: 0 0 0 4px var(--shadow);
105 | }
106 |
107 | .dark .button_primary:focus {
108 | --shadow: #404040;
109 | }
110 |
111 | .button_size__md {
112 | height: 40px;
113 | min-width: 40px;
114 | padding-inline: 16px;
115 | line-height: 1.25rem;
116 | font-size: 0.875rem;
117 | }
118 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/number-input/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | NumberInput,
3 | NumberInputControl,
4 | NumberInputDecrementTrigger,
5 | NumberInputField,
6 | NumberInputIncrementTrigger,
7 | NumberInputScrubber,
8 | } from "@ark-ui/react";
9 |
10 | import ChevronDownIcon from "./ChevronDownIcon";
11 | import ChevronUpIcon from "./ChevronUpIcon";
12 | import "./styles.css";
13 |
14 | export default function Page() {
15 | return (
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 |
29 |
30 |
31 |
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/number-input/ChevronDownIcon.js:
--------------------------------------------------------------------------------
1 | export default function ChevronDownIcon() {
2 | return (
3 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/number-input/ChevronUpIcon.js:
--------------------------------------------------------------------------------
1 | export default function ChevronUpIcon() {
2 | return (
3 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/number-input/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | "/ChevronUpIcon.js": require("./ChevronUpIcon.js").default,
8 | "/ChevronDownIcon.js": require("./ChevronDownIcon.js").default,
9 | ...sharedReactCode,
10 | },
11 | visibleFiles: [
12 | "/App.js",
13 | "/styles.css",
14 | "/ChevronUpIcon.js",
15 | "/ChevronDownIcon.js",
16 | ],
17 | };
18 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/number-input/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="number-input"][data-part="root"] {
2 | --border-default: #e7e5e4;
3 | --border-emphasized: #a6a6a6;
4 | --bg-surface: #fff;
5 | --bg-subtle: #d9d9d91e;
6 | --accent-default: #60a5fa;
7 | --fg-emphasized: #404040;
8 | --fg-subtle: #ededed;
9 |
10 | border: solid 1px;
11 | border-color: var(--border-emphasized);
12 | border-radius: 0.5rem;
13 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
14 | 0px 1px 2px rgba(48, 49, 51, 0.1);
15 | display: flex;
16 | overflow: hidden;
17 | padding-left: 12px;
18 | height: 40px;
19 | min-width: 40px;
20 | line-height: 1.5rem;
21 | font-size: 1rem;
22 | width: 100%;
23 | }
24 |
25 | [data-scope="number-input"][data-part="root"]:focus-within {
26 | z-index: 1;
27 | box-shadow: 0 0 0 1px #8b5cf6;
28 | border-color: var(--accent-default);
29 | }
30 |
31 | .dark [data-scope="number-input"][data-part="root"]:focus-within {
32 | box-shadow: 0 0 0 1px #ddd6fe;
33 | }
34 |
35 | .dark [data-scope="number-input"][data-part="root"] {
36 | --border-default: #3e3e3e;
37 | --border-emphasized: #262626;
38 | --bg-surface: #111;
39 | --bg-subtle: #3333335e;
40 | --fg-emphasized: #bfbfbf;
41 | --fg-subtle: #262626;
42 |
43 | box-shadow: 0px 0px 1px #0d0d0d, 0px 1px 2px rgba(13, 13, 13, 0.9);
44 | }
45 |
46 | [data-scope="number-input"][data-part="control"] {
47 | width: 100%;
48 | display: flex;
49 | flex-direction: column;
50 | border-left: solid 1px;
51 | border-color: var(--border-emphasized);
52 | }
53 |
54 | [data-scope="number-input"][data-part="input"] {
55 | all: unset;
56 | background: var(--bg-surface);
57 | color: #0d0d0d;
58 | outline: none;
59 | }
60 |
61 | .dark [data-scope="number-input"][data-part="input"] {
62 | color: white;
63 | }
64 |
65 | [data-scope="number-input"][data-part="increment-trigger"],
66 | [data-scope="number-input"][data-part="decrement-trigger"] {
67 | all: unset;
68 | align-items: center;
69 | appearance: none;
70 | cursor: pointer;
71 | display: inline-flex;
72 | font-weight: 600;
73 | justify-content: center;
74 | outline: none;
75 | position: relative;
76 | transition-property: color, background-color, border-color, outline-color,
77 | text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
78 | backdrop-filter;
79 | transition-duration: 100ms;
80 | transition-timing-function: ease-out;
81 | user-select: none;
82 | vertical-align: middle;
83 | white-space: nowrap;
84 |
85 | background: var(--bg-surface);
86 | color: var(--fg-emphasized);
87 | flex: 1;
88 | }
89 |
90 | [data-scope="number-input"][data-part="increment-trigger"]:hover,
91 | [data-scope="number-input"][data-part="decrement-trigger"]:hover {
92 | background: var(--bg-subtle);
93 | }
94 |
95 | [data-scope="number-input"][data-part="increment-trigger"]:disabled,
96 | [data-scope="number-input"][data-part="decrement-trigger"]:disabled {
97 | border: var(--border-default);
98 | cursor: not-allowed;
99 | color: var(--fg-subtle);
100 | }
101 |
102 | [data-scope="number-input"][data-part="increment-trigger"] {
103 | border-bottom: solid 1px;
104 | border-color: var(--border-emphasized);
105 | }
106 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/pagination/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Pagination,
3 | PaginationEllipsis,
4 | PaginationList,
5 | PaginationNextPageTrigger,
6 | PaginationPageTrigger,
7 | PaginationPrevPageTrigger,
8 | } from "@ark-ui/react";
9 |
10 | import "./styles.css";
11 |
12 | export default function Page() {
13 | return (
14 |
15 | {({ pages }) => (
16 | <>
17 |
18 |
19 |
22 |
23 |
24 | {pages.map((page, index) =>
25 | page.type === "page" ? (
26 |
27 |
30 |
31 | ) : (
32 |
33 | …
34 |
35 | )
36 | )}
37 |
38 |
39 |
42 |
43 |
44 | >
45 | )}
46 |
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/pagination/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/pagination/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="pagination"][data-part="root"] {
2 | --fg-emphasized: #404040;
3 |
4 | display: flex;
5 | justify-content: space-between;
6 | }
7 |
8 | .dark [data-scope="pagination"][data-part="root"] {
9 | --fg-emphasized: #bfbfbf;
10 | }
11 |
12 | [data-scope="pagination"][data-part="list"] {
13 | display: flex;
14 | list-style: none;
15 | padding: 0;
16 | gap: 4px;
17 | }
18 |
19 | [data-scope="pagination"][data-part="page-trigger"] {
20 | font-variant-numeric: tabular-nums;
21 | }
22 |
23 | [data-scope="pagination"][data-part="ellipsis"] {
24 | display: inline-flex;
25 | align-items: center;
26 | justify-content: center;
27 | height: 40px;
28 | min-width: 40px;
29 | color: var(--fg-emphasized);
30 | font-size: 0.875rem;
31 | user-select: none;
32 | }
33 |
34 | .button {
35 | all: unset;
36 | align-items: center;
37 | appearance: none;
38 | border-radius: 0.5rem;
39 | cursor: pointer;
40 | display: inline-flex;
41 | font-weight: 500;
42 | justify-content: center;
43 | outline: none;
44 | position: relative;
45 | transition-property: color, background-color, border-color, outline-color,
46 | text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
47 | backdrop-filter;
48 | transition-duration: 100ms;
49 | transition-timing-function: ease-out;
50 | user-select: none;
51 | vertical-align: middle;
52 | white-space: nowrap;
53 |
54 | --fg-default: #0d0d0d;
55 | --bg-subtle: #d9d9d9;
56 | }
57 |
58 | .dark .button {
59 | --fg-default: white;
60 | --bg-subtle: #262626;
61 | }
62 |
63 | .button_size__md {
64 | height: 40px;
65 | min-width: 40px;
66 | padding-inline: 16px;
67 | line-height: 1.25rem;
68 | font-size: 0.875rem;
69 | }
70 |
71 | .button_secondary {
72 | border: solid 1px;
73 | background: white;
74 | border-color: #a6a6a6;
75 | color: #404040;
76 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
77 | 0px 1px 2px rgba(48, 49, 51, 0.1);
78 | }
79 |
80 | .button_secondary:focus {
81 | z-index: 1;
82 | box-shadow: 0 0 0 4px #d9d9d9;
83 | }
84 | .dark .button_secondary {
85 | background: #191919;
86 | border-color: #262626;
87 | color: #bfbfbf;
88 | box-shadow: 0px 0px 1px #0d0d0d, 0px 1px 2px rgba(13, 13, 13, 0.9);
89 | }
90 |
91 | .dark .button_secondary:focus {
92 | box-shadow: 0 0 0 4px #262626;
93 | }
94 |
95 | .button_secondary:hover {
96 | color: var(--fg-default);
97 | background: var(--bg-subtle);
98 | }
99 |
100 | .button_tertiary {
101 | padding-inline: 0px;
102 | background: transparent;
103 | color: var(--fg-emphasized);
104 | }
105 |
106 | .button_tertiary:focus {
107 | z-index: 1;
108 | box-shadow: 0 0 0 4px #d9d9d9;
109 | }
110 |
111 | .dark .button_tertiary:focus {
112 | box-shadow: 0 0 0 4px #262626;
113 | }
114 |
115 | .button_tertiary:hover {
116 | color: var(--fg-default);
117 | background: var(--bg-subtle);
118 | }
119 |
120 | .dark .button_tertiary {
121 | color: #737373;
122 | }
123 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/pin-input/App.js:
--------------------------------------------------------------------------------
1 | import { PinInput, PinInputControl, PinInputField } from "@ark-ui/react";
2 |
3 | import "./styles.css";
4 |
5 | export default function Page() {
6 | return (
7 | alert(e.valueAsString)}>
8 |
9 | {[0, 1, 2, 3].map((id, index) => (
10 |
11 | ))}
12 |
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/pin-input/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/pin-input/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="pin-input"][data-part="root"] {
2 | --bg-surface: #fff;
3 | --border-default: #e7e5e4;
4 | }
5 |
6 | .dark [data-scope="pin-input"][data-part="root"] {
7 | --bg-surface: #111;
8 | --border-default: #3e3e3e;
9 | }
10 |
11 | [data-scope="pin-input"][data-part="control"] {
12 | display: flex;
13 | gap: 8px;
14 | }
15 |
16 | [data-scope="pin-input"][data-part="input"] {
17 | all: unset;
18 | background: var(--bg-surface);
19 | color: #0d0d0d;
20 |
21 | border: solid 1px;
22 | border-color: var(--border-default);
23 | border-radius: 0.5rem;
24 |
25 | font-size: 1.875rem;
26 | line-height: 2.375rem;
27 | height: 64px;
28 | width: 64px;
29 | text-align: center;
30 | }
31 |
32 | [data-scope="pin-input"][data-part="input"]:focus {
33 | z-index: 1;
34 | box-shadow: 0 0 0 1px #8b5cf6;
35 | border-color: #60a5fa;
36 | }
37 |
38 | .dark [data-scope="pin-input"][data-part="input"]:focus {
39 | box-shadow: 0 0 0 1px #ddd6fe;
40 | }
41 |
42 | .dark [data-scope="pin-input"][data-part="input"] {
43 | color: white;
44 | }
45 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/popover/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Popover,
3 | PopoverArrow,
4 | PopoverArrowTip,
5 | PopoverCloseTrigger,
6 | PopoverContent,
7 | PopoverDescription,
8 | PopoverPositioner,
9 | PopoverTitle,
10 | PopoverTrigger,
11 | } from "@ark-ui/react";
12 |
13 | import "./styles.css";
14 |
15 | export default function Page() {
16 | return (
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
Favorite Cake
31 |
32 | Dessert jelly beans pudding chocolate pie pastry danish
33 | chocolate pie.
34 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
46 |
47 |
48 |
49 |
50 |
51 | );
52 | }
53 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/popover/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/popover/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="popover"][data-part="positioner"] {
2 | --bg-surface: #fafaf9;
3 | --border-default: #e7e5e4;
4 |
5 | background: var(--bg-surface);
6 | border: solid 1px var(--border-default);
7 | z-index: 1;
8 | border-radius: 0.5rem;
9 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
10 | 0px 8px 16px rgba(48, 49, 51, 0.1);
11 | }
12 |
13 | .dark [data-scope="popover"][data-part="positioner"] {
14 | --bg-surface: #111;
15 | --border-default: #3e3e3e;
16 | box-shadow: 0px 0px 1px #0d0d0d, 0px 8px 16px rgba(13, 13, 13, 0.9);
17 | }
18 |
19 | [data-scope="popover"][data-part="content"] {
20 | max-width: 24rem;
21 | padding: 12px;
22 | position: relative;
23 | }
24 |
25 | [data-scope="popover"][data-part="title"] {
26 | font-weight: 600;
27 | font-size: 0.875rem;
28 | line-height: 1.25rem;
29 | }
30 |
31 | [data-scope="popover"][data-part="description"] {
32 | font-size: 0.875rem;
33 | line-height: 1.25rem;
34 | color: #737373;
35 | }
36 |
37 | .dark [data-scope="popover"][data-part="description"] {
38 | color: #8c8c8c;
39 | }
40 |
41 | [data-scope="popover"][data-part="arrow"] {
42 | /* This variables are consumed by ark ui */
43 | --arrow-size: 12px;
44 | --arrow-background: var(--bg-surface);
45 | }
46 |
47 | [data-scope="popover"][data-part="arrow-tip"] {
48 | border-top: solid 1px var(--border-default);
49 | border-left: solid 1px var(--border-default);
50 | }
51 |
52 | .input {
53 | all: unset;
54 | background: var(--bg-surface);
55 | color: #0d0d0d;
56 |
57 | padding-inline: 10px;
58 | height: 36px;
59 | min-width: 36px;
60 | font-size: 0.875rem;
61 | line-height: 1.25rem;
62 |
63 | border: solid 1px;
64 | border-color: var(--border-default);
65 | border-radius: 0.5rem;
66 | }
67 |
68 | .input:focus {
69 | z-index: 1;
70 | box-shadow: 0 0 0 1px #8b5cf6;
71 | border-color: #60a5fa;
72 | }
73 |
74 | .button {
75 | all: unset;
76 | align-items: center;
77 | appearance: none;
78 | border-radius: 0.5rem;
79 | cursor: pointer;
80 | display: inline-flex;
81 | font-weight: 500;
82 | justify-content: center;
83 | outline: none;
84 | position: relative;
85 | transition-property: color, background-color, border-color, outline-color,
86 | text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
87 | backdrop-filter;
88 | transition-duration: 100ms;
89 | transition-timing-function: ease-out;
90 | user-select: none;
91 | vertical-align: middle;
92 | white-space: nowrap;
93 | }
94 |
95 | .button_size__sm {
96 | height: 36px;
97 | min-width: 36px;
98 | padding-inline: 14px;
99 | line-height: 1.25rem;
100 | font-size: 0.875rem;
101 | }
102 |
103 | .button_size__md {
104 | height: 40px;
105 | min-width: 40px;
106 | padding-inline: 16px;
107 | line-height: 1.25rem;
108 | font-size: 0.875rem;
109 | }
110 |
111 | .button_secondary {
112 | border: solid 1px;
113 | background: white;
114 | border-color: #a6a6a6;
115 | color: #404040;
116 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
117 | 0px 1px 2px rgba(48, 49, 51, 0.1);
118 | }
119 |
120 | .button_secondary:focus {
121 | z-index: 1;
122 | box-shadow: 0 0 0 4px #d9d9d9;
123 | }
124 | .dark .button_secondary {
125 | background: #191919;
126 | border-color: #262626;
127 | color: #bfbfbf;
128 | box-shadow: 0px 0px 1px #0d0d0d, 0px 1px 2px rgba(13, 13, 13, 0.9);
129 | }
130 |
131 | .dark .button_secondary:focus {
132 | box-shadow: 0 0 0 4px #262626;
133 | }
134 |
135 | .button_link {
136 | color: #737373;
137 | background: transparent;
138 | height: auto;
139 | padding: 0;
140 | }
141 |
142 | .dark .button_link {
143 | color: #8c8c8c;
144 | }
145 |
146 | .button_link:hover {
147 | color: #404040;
148 | }
149 |
150 | .dark .button_link:hover {
151 | color: #bfbfbf;
152 | }
153 |
154 | .stack {
155 | display: flex;
156 | flex-direction: column;
157 | gap: 4px;
158 | }
159 |
160 | .row {
161 | flex-direction: row;
162 | }
163 |
164 | .content {
165 | gap: 16px;
166 | }
167 |
168 | .actions {
169 | gap: 12px;
170 | }
171 |
172 | .active,
173 | .dark .active {
174 | color: #a78bfa;
175 | }
176 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/radio-group/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Radio,
3 | RadioControl,
4 | RadioGroup,
5 | RadioInput,
6 | RadioLabel,
7 | } from "@ark-ui/react";
8 |
9 | import "./styles.css";
10 |
11 | const options = [
12 | { id: "react", label: "React" },
13 | { id: "solid", label: "Solid" },
14 | { id: "vue", label: "Vue" },
15 | ];
16 |
17 | export default function Page() {
18 | return (
19 |
20 | {options.map((option, id) => (
21 |
22 |
23 |
24 | {option.label}
25 |
26 | ))}
27 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/radio-group/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/radio-group/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="radio-group"][data-part="root"] {
2 | --bg-surface: #fafaf9;
3 | --border-emphasized: #a6a6a6;
4 |
5 | display: flex;
6 | cursor: pointer;
7 | flex-direction: column;
8 | gap: 16px;
9 | }
10 |
11 | .dark [data-scope="radio-group"][data-part="root"] {
12 | --bg-surface: #111;
13 | --border-emphasized: #262626;
14 | }
15 |
16 | [data-scope="radio-group"][data-part="radio"] {
17 | align-items: center;
18 | cursor: pointer;
19 | display: flex;
20 | gap: 12px;
21 | }
22 |
23 | [data-scope="radio-group"][data-part="radio-control"] {
24 | height: 20px;
25 | width: 20px;
26 | border: solid 1px var(--border-emphasized);
27 | border-radius: 9999px;
28 | background: var(--bg-surface);
29 | }
30 |
31 | [data-peer]:focus ~ [data-scope="radio-group"][data-part="radio-control"] {
32 | box-shadow: 0 0 0 4px #ede9fe;
33 | }
34 |
35 | .dark
36 | [data-peer]:focus
37 | ~ [data-scope="radio-group"][data-part="radio-control"] {
38 | box-shadow: 0 0 0 4px #262626;
39 | }
40 |
41 | [data-scope="radio-group"][data-part="radio-control"]:hover {
42 | border-color: #8c8c8c;
43 | }
44 |
45 | .dark [data-scope="radio-group"][data-part="radio-control"]:hover {
46 | border-color: #404040;
47 | }
48 |
49 | [data-scope="radio-group"][data-part="radio-control"][data-checked] {
50 | background: #a78bfa;
51 | border-color: #a78bfa;
52 | outline-style: solid;
53 | outline-width: 3px;
54 | outline-offset: -4px;
55 | outline-color: white;
56 | }
57 |
58 | .dark [data-scope="radio-group"][data-part="radio-control"][data-checked] {
59 | outline-color: #0d0d0d;
60 | }
61 |
62 | [data-scope="radio-group"][data-part="radio-label"] {
63 | font-weight: 500;
64 | color: #404040;
65 | }
66 |
67 | .dark [data-scope="radio-group"][data-part="radio-label"] {
68 | color: #bfbfbf;
69 | }
70 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/range-slider/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | RangeSlider,
3 | RangeSliderControl,
4 | RangeSliderMarker,
5 | RangeSliderMarkerGroup,
6 | RangeSliderRange,
7 | RangeSliderThumb,
8 | RangeSliderTrack,
9 | } from "@ark-ui/react";
10 |
11 | import "./styles.css";
12 |
13 | export default function Page() {
14 | return (
15 |
16 |
17 |
18 |
19 |
20 | {[0, 1].map((i) => (
21 |
22 | ))}
23 |
24 |
25 | 25
26 | 50
27 | 75
28 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/range-slider/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!../slider/styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/rating-group/App.js:
--------------------------------------------------------------------------------
1 | import { Rating, RatingGroup, RatingGroupControl } from "@ark-ui/react";
2 |
3 | import "./styles.css";
4 |
5 | export default function Page() {
6 | return (
7 |
8 |
9 | {({ sizeArray }) =>
10 | sizeArray.map((index) => (
11 |
12 | {({ isHalf }) => }
13 |
14 | ))
15 | }
16 |
17 |
18 | );
19 | }
20 |
21 | // SVG Icon for Rating Stars. Feel free to use any solution of your choice
22 | const Icon = (props) => (
23 |
45 | );
46 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/rating-group/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/rating-group/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="rating-group"][data-part="control"] {
2 | display: flex;
3 | gap: 2px;
4 | }
5 |
6 | [data-scope="rating-group"][data-part="rating"] {
7 | cursor: pointer;
8 | color: #a6a6a6;
9 | fill: #a6a6a6;
10 | transition-property: color, fill;
11 | transition-duration: 50ms;
12 | --stop-color-active: #a78bfa;
13 | --stop-color-inactive: #a6a6a6;
14 | }
15 |
16 | .dark [data-scope="rating-group"][data-part="rating"] {
17 | color: #262626;
18 | fill: #262626;
19 | --stop-color-inactive: #262626;
20 | }
21 |
22 | [data-scope="rating-group"][data-part="rating"][data-focus] {
23 | outline: none;
24 | }
25 |
26 | [data-scope="rating-group"][data-part="rating"] svg {
27 | width: 40px;
28 | height: 40px;
29 | }
30 |
31 | [data-scope="rating-group"][data-part="rating"][data-highlighted] {
32 | color: #a78bfa;
33 | fill: #a78bfa;
34 | }
35 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/select/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Portal,
3 | Select,
4 | SelectContent,
5 | SelectOption,
6 | SelectOptionGroup,
7 | SelectOptionGroupLabel,
8 | SelectPositioner,
9 | SelectTrigger,
10 | } from "@ark-ui/react";
11 |
12 | import SelectIcon from "./SelectIcon";
13 | import "./styles.css";
14 |
15 | export default function Page() {
16 | return (
17 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/select/SelectIcon.js:
--------------------------------------------------------------------------------
1 | export default function SelectIcon(props) {
2 | const iconStyles = {
3 | transform: props.isOpen ? "rotate(-180deg)" : undefined,
4 | transition: "transform 0.2s",
5 | transformOrigin: "center",
6 | };
7 | return (
8 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/select/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | "/SelectIcon.js": require("./SelectIcon.js").default,
8 | ...sharedReactCode,
9 | },
10 | visibleFiles: ["/App.js", "/styles.css", "/SelectIcon.js"],
11 | };
12 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/select/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="select"][data-part="trigger"] {
2 | all: unset;
3 |
4 | padding: 0 0.75rem;
5 | height: 40px;
6 | width: 20rem;
7 | font-size: 1rem;
8 | line-height: 1.5rem;
9 |
10 | display: flex;
11 | align-items: center;
12 | justify-content: space-between;
13 | cursor: pointer;
14 | outline: 0;
15 | position: relative;
16 | appearance: none;
17 | transition-property: color, background-color, border-color, opacity,
18 | box-shadow;
19 | transition-duration: 100ms;
20 |
21 | border-radius: 0.5rem;
22 | border: solid 1px #e7e5e4;
23 | background-color: #fafaf9;
24 | text-align: left;
25 |
26 | color: #0d0d0d;
27 | }
28 |
29 | .dark [data-scope="select"][data-part="trigger"] {
30 | border-color: #3e3e3e;
31 | background-color: #111;
32 | color: white;
33 | }
34 |
35 | [data-scope="select"][data-part="trigger"]:focus {
36 | z-index: 1;
37 | border-color: #a78bfa;
38 | box-shadow: 0 0 0 4px #eff6ff;
39 | }
40 |
41 | .dark [data-scope="select"][data-part="trigger"]:focus {
42 | box-shadow: 0 0 0 4px #404040;
43 | }
44 |
45 | [data-scope="select"][data-part="trigger"]:disabled {
46 | opacity: 0.4;
47 | cursor: not-allowed;
48 | }
49 |
50 | [data-scope="select"][data-part="content"] {
51 | background-color: #fafaf9;
52 | border-radius: 0.5rem;
53 | max-width: calc(100vw - 1rem);
54 | /* Width of trigger + inline-padding of trigger */
55 | width: 20.75rem;
56 | padding: 4px;
57 | list-style: none;
58 | border: solid 1px #e7e5e4;
59 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
60 | 0px 8px 16px rgba(48, 49, 51, 0.1);
61 | }
62 |
63 | .dark [data-scope="select"][data-part="content"] {
64 | background-color: #111;
65 | border-color: #3e3e3e;
66 | box-shadow: 0px 0px 1px #0d0d0d, 0px 8px 16px rgba(13, 13, 13, 0.9);
67 | }
68 |
69 | [data-scope="select"][data-part="option"] {
70 | padding: 8px;
71 | font-size: 1rem;
72 | line-height: 1.5rem;
73 |
74 | border-radius: 0.375rem;
75 | cursor: pointer;
76 | margin-bottom: 4px;
77 | }
78 |
79 | [data-scope="select"][data-part="option"]:hover,
80 | [data-scope="select"][data-part="option"][data-selected],
81 | [data-scope="select"][data-part="option"][data-selefocuscted] {
82 | background: #d9d9d9;
83 | }
84 |
85 | .dark [data-scope="select"][data-part="option"]:hover,
86 | .dark [data-scope="select"][data-part="option"][data-selected],
87 | .dark [data-scope="select"][data-part="option"][data-selefocuscted] {
88 | background: #262626;
89 | }
90 |
91 | [data-scope="select"][data-part="option"]:last-child {
92 | margin-bottom: 0;
93 | }
94 |
95 | [data-scope="select"][data-part="option-group-label"] {
96 | user-select: none;
97 | padding: 8px;
98 | font-size: 0.9rem;
99 | font-weight: 500;
100 | text-transform: uppercase;
101 | }
102 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/slider/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Slider,
3 | SliderControl,
4 | SliderMarker,
5 | SliderMarkerGroup,
6 | SliderRange,
7 | SliderThumb,
8 | SliderTrack,
9 | } from "@ark-ui/react";
10 |
11 | import "./styles.css";
12 |
13 | export default function Page() {
14 | return (
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | 25
24 | 50
25 | 75
26 |
27 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/slider/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/slider/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="slider"][data-part="root"] {
2 | --bg-surface: #fafaf9;
3 | --border-default: #e7e5e4;
4 |
5 | width: 450px;
6 | }
7 |
8 | .dark [data-scope="slider"][data-part="root"] {
9 | --bg-surface: #111;
10 | --border-default: #3e3e3e;
11 | }
12 |
13 | [data-scope="slider"][data-part="control"] {
14 | position: relative;
15 | display: flex;
16 | align-items: center;
17 | padding-block: 8px;
18 | }
19 |
20 | [data-scope="slider"][data-part="track"] {
21 | background: var(--border-default);
22 | border-radius: 0.25rem;
23 | flex: 1;
24 | height: 8px;
25 | }
26 |
27 | [data-scope="slider"][data-part="range"] {
28 | background: #a78bfa;
29 | border-radius: 0.25rem;
30 | height: 8px;
31 | }
32 |
33 | [data-scope="slider"][data-part="thumb"] {
34 | border: solid 1.5px #a78bfa;
35 | background: var(--bg-surface);
36 | border-radius: 9999px;
37 | outline: none;
38 | height: 24px;
39 | width: 24px;
40 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
41 | 0px 2px 4px rgba(48, 49, 51, 0.1);
42 | }
43 |
44 | .dark [data-scope="slider"][data-part="thumb"] {
45 | box-shadow: 0px 0px 1px #0d0d0d, 0px 2px 4px rgba(13, 13, 13, 0.9);
46 | }
47 |
48 | [data-scope="slider"][data-part="thumb"][data-focus] {
49 | outline: none;
50 | box-shadow: 0 0 0 4px #ede9fec5;
51 | }
52 |
53 | .dark [data-scope="slider"][data-part="thumb"][data-focus] {
54 | box-shadow: 0 0 0 4px #262626b5;
55 | }
56 |
57 | [data-scope="slider"][data-part="marker"] {
58 | margin-top: 8px;
59 | font-size: 1rem;
60 | line-height: 1.5rem;
61 | }
62 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/splitter/App.js:
--------------------------------------------------------------------------------
1 | import { Splitter, SplitterPanel, SplitterResizeTrigger } from "@ark-ui/react";
2 | import { useId } from "react";
3 |
4 | import "./styles.css";
5 |
6 | // Ark UI allows us to nest splitters
7 | export default function Page() {
8 | return (
9 |
10 | Arkxamples 😉
}
13 | >
14 | React}>
15 | Vue}
18 | >
19 | Solid
20 |
21 |
22 |
23 |
24 | );
25 | }
26 |
27 | const BasicSplitter = (props) => {
28 | const [first, second] = [useId(), useId()].map((id) => id.replace(/:/g, "-"));
29 | return (
30 | <>
31 |
38 | {props.content}
39 |
40 |
41 |
42 | {props.children}
43 |
44 | >
45 | );
46 | };
47 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/splitter/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/splitter/styles.css:
--------------------------------------------------------------------------------
1 | .container {
2 | height: 40rem;
3 | width: 40rem;
4 | }
5 |
6 | .content {
7 | color: #595959;
8 | background: #e7e5e4;
9 | flex: 1;
10 | display: flex;
11 | align-items: center;
12 | justify-content: center;
13 | border-radius: 0.5rem;
14 | padding: 16px;
15 | }
16 |
17 | .dark .content {
18 | color: #8c8c8c;
19 | background: #262626;
20 | }
21 |
22 | [data-scope="splitter"][data-part="root"] {
23 | gap: 8px;
24 | width: 100%;
25 | }
26 |
27 | [data-scope="splitter"][data-part="panel"] {
28 | display: flex;
29 | overflow: auto;
30 | flex: 1;
31 | }
32 |
33 | [data-scope="splitter"][data-part="resize-trigger"] {
34 | display: flex;
35 | align-items: center;
36 | justify-content: center;
37 | border-radius: 0.5rem;
38 | outline: 0;
39 | position: relative;
40 | background: #e7e5e4;
41 | transition: background-color 0.2s ease-in-out;
42 | }
43 |
44 | .dark [data-scope="splitter"][data-part="resize-trigger"] {
45 | background: #737373;
46 | }
47 |
48 | [data-scope="splitter"][data-part="resize-trigger"][data-orientation="horizontal"] {
49 | width: 4px;
50 | margin: min(1rem, 20%) 0;
51 | min-height: 50px;
52 | }
53 |
54 | [data-scope="splitter"][data-part="resize-trigger"][data-orientation="vertical"] {
55 | min-height: 4px;
56 | margin: 0 min(1rem, 20%);
57 | }
58 |
59 | [data-scope="splitter"][data-part="resize-trigger"]:hover,
60 | [data-scope="splitter"][data-part="resize-trigger"][data-focus] {
61 | background: #3b82f6;
62 | }
63 |
64 | .dark [data-scope="splitter"][data-part="resize-trigger"]:hover,
65 | .dark [data-scope="splitter"][data-part="resize-trigger"][data-focus] {
66 | background: #bfdbfe;
67 | }
68 |
69 | [data-scope="splitter"][data-part="resize-trigger"][data-focus] {
70 | box-shadow: 0 0 0 4px #ede9fec5;
71 | }
72 |
73 | .dark [data-scope="splitter"][data-part="resize-trigger"][data-focus] {
74 | box-shadow: 0 0 0 4px #262626b5;
75 | }
76 |
77 | [data-scope="splitter"][data-part="resize-trigger"][disabled] {
78 | opacity: 0.5;
79 | }
80 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/tabs/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | TabContent,
3 | TabIndicator,
4 | TabList,
5 | TabTrigger,
6 | Tabs,
7 | } from "@ark-ui/react";
8 |
9 | import "./styles.css";
10 |
11 | export default function Page() {
12 | return (
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | A JavaScript library for building user interfaces
28 |
29 |
30 | Simple and performant reactivity for building user interfaces.
31 |
32 |
33 | An approachable, performant and versatile framework for building web
34 | user interfaces.
35 |
36 |
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/tabs/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/tabs/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="tabs"][data-part="root"] {
2 | width: 30rem;
3 | }
4 |
5 | [data-scope="tabs"][data-part="tablist"] {
6 | border-bottom: solid 1px;
7 | border-color: #e7e5e4;
8 | display: flex;
9 | gap: 16px;
10 | height: 32px;
11 | position: relative;
12 | }
13 |
14 | .dark [data-scope="tabs"][data-part="tablist"] {
15 | border-bottom: solid 1px;
16 | border-color: #3e3e3e;
17 | }
18 |
19 | [data-scope="tabs"][data-part="trigger"] {
20 | all: unset;
21 | background: transparent;
22 | cursor: pointer;
23 | display: inline-flex;
24 | font-weight: 600;
25 | padding-inline: 4px;
26 | color: #737373;
27 | font-size: 0.875rem;
28 | line-height: 1.25rem;
29 | }
30 |
31 | .dark [data-scope="tabs"][data-part="trigger"] {
32 | color: #8c8c8c;
33 | }
34 |
35 | [data-scope="tabs"][data-part="trigger"]:hover {
36 | color: #404040;
37 | }
38 |
39 | .dark [data-scope="tabs"][data-part="trigger"]:hover {
40 | color: #bfbfbf;
41 | }
42 |
43 | [data-scope="tabs"][data-part="trigger"][data-selected] {
44 | color: #60a5fa;
45 | }
46 |
47 | .dark [data-scope="tabs"][data-part="trigger"][data-selected] {
48 | color: #93c5fd;
49 | }
50 |
51 | [data-scope="tabs"][data-part="trigger"][data-disabled] {
52 | opacity: 0.4;
53 | cursor: not-allowed;
54 | }
55 |
56 | [data-scope="tabs"][data-part="indicator"] {
57 | height: 2px;
58 | background: #60a5fa;
59 | bottom: -1px;
60 | }
61 |
62 | .dark [data-scope="tabs"][data-part="indicator"] {
63 | background: #93c5fd;
64 | }
65 |
66 | [data-scope="tabs"][data-part="content"] {
67 | border: solid 1px;
68 | border-radius: 0.5rem;
69 | border-top-left-radius: 0px;
70 | border-top-right-radius: 0px;
71 | border-top-width: 0px;
72 | min-height: 10rem;
73 | padding: 16px;
74 | color: #595959;
75 | background: #e7e5e4;
76 | border-color: #e7e5e4;
77 | }
78 |
79 | .dark [data-scope="tabs"][data-part="content"] {
80 | color: #8c8c8c;
81 | background: #262626;
82 | border-color: #3e3e3e;
83 | }
84 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/tags-input/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Tag,
3 | TagDeleteTrigger,
4 | TagInput,
5 | TagsInput,
6 | TagsInputControl,
7 | TagsInputField,
8 | } from "@ark-ui/react";
9 | import { Fragment } from "react";
10 |
11 | import "./styles.css";
12 |
13 | export default function Page() {
14 | return (
15 |
16 | {({ value }) => (
17 |
18 | {(value ?? []).map((value, index) => (
19 |
20 |
21 | {value}
22 |
23 |
40 |
41 |
42 |
43 |
44 | ))}
45 |
46 |
47 | )}
48 |
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/tags-input/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/tags-input/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="tags-input"][data-part="root"] {
2 | width: 40rem;
3 | }
4 |
5 | [data-scope="tags-input"][data-part="control"] {
6 | color: #0d0d0d;
7 | background: #fafaf9;
8 | border: solid 1px #a6a6a6;
9 | border-radius: 0.5rem;
10 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
11 | 0px 1px 2px rgba(48, 49, 51, 0.1);
12 | display: flex;
13 | flex-wrap: wrap;
14 | gap: 6px;
15 | padding: 12px;
16 | transition-property: color, background-color, border-color opacity, box-shadow;
17 | transition-duration: 100ms;
18 | font-weight: 500;
19 | font-size: 0.875rem;
20 | line-height: 1.25rem;
21 | }
22 |
23 | .dark [data-scope="tags-input"][data-part="control"] {
24 | color: white;
25 | background: #111;
26 | border-color: #3e3e3e;
27 |
28 | box-shadow: 0px 0px 1px #0d0d0d, 0px 1px 2px rgba(13, 13, 13, 0.9);
29 | }
30 |
31 | [data-scope="tags-input"][data-part="control"]:focus-within {
32 | z-index: 1;
33 | border-color: #a78bfa;
34 | box-shadow: 0 0 0 1px #8b5cf6;
35 | }
36 |
37 | .dark [data-scope="tags-input"][data-part="control"]:focus-within {
38 | box-shadow: 0 0 0 1px #ddd6fe;
39 | }
40 |
41 | [data-scope="tags-input"][data-part="input"] {
42 | all: unset;
43 | }
44 |
45 | [data-scope="tags-input"][data-part="tag"] {
46 | display: inline-flex;
47 | align-items: center;
48 | justify-content: center;
49 | border: solid 1px #a6a6a6;
50 | border-radius: 0.5rem;
51 | height: 24px;
52 | padding-left: 10px;
53 | padding-right: 4px;
54 | font: inherit;
55 | }
56 |
57 | .dark [data-scope="tags-input"][data-part="tag"] {
58 | border-color: #3e3e3e;
59 | }
60 |
61 | [data-scope="tags-input"][data-part="tag"][data-selected] {
62 | z-index: 1;
63 | border-color: #a78bfa;
64 | }
65 |
66 | [data-scope="tags-input"][data-part="tag"][hidden] {
67 | display: none;
68 | }
69 |
70 | [data-scope="tags-input"][data-part="tag-input"] {
71 | border: none;
72 | outline: none;
73 | font: inherit;
74 | background: transparent;
75 | padding-left: 10px;
76 | /*
77 | Gap before next Tag (6) + width of delete icon (12)
78 | + margin before delete icon (4) + tag right padding (4)
79 |
80 | You can just put a small padding, or same as padding-left.
81 | I only do this because I like the text to remain in the same
82 | position once I start editing. This choice is subjective.
83 | */
84 | padding-right: 25px;
85 | }
86 |
87 | [data-scope="tags-input"][data-part="tag-delete-trigger"] {
88 | all: unset;
89 | display: inline-flex;
90 | align-items: center;
91 | justify-content: center;
92 | cursor: pointer;
93 | background: transparent;
94 | height: 16px;
95 | width: 16px;
96 | margin-left: 4px;
97 | color: #8c8c8c;
98 | }
99 |
100 | .dark [data-scope="tags-input"][data-part="tag-delete-trigger"] {
101 | color: #737373;
102 | }
103 |
104 | [data-scope="tags-input"][data-part="tag-delete-trigger"] svg {
105 | height: 12px;
106 | width: 12px;
107 | }
108 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/toast/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Portal,
3 | Toast,
4 | ToastCloseTrigger,
5 | ToastDescription,
6 | ToastGroup,
7 | ToastPlacements,
8 | ToastProvider,
9 | ToastTitle,
10 | useToast,
11 | } from "@ark-ui/react";
12 |
13 | import CloseIcon from "./CloseIcon";
14 | import "./styles.css";
15 |
16 | export default function Page() {
17 | return (
18 |
19 |
20 |
21 | {(placements) =>
22 | placements.map((placement) => (
23 |
24 | {(toasts) =>
25 | toasts.map((toast) => (
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
37 |
38 |
41 |
42 |
43 |
44 |
50 |
51 |
52 | ))
53 | }
54 |
55 | ))
56 | }
57 |
58 |
59 |
60 |
61 | );
62 | }
63 |
64 | const ToastTrigger = () => {
65 | const toast = useToast();
66 |
67 | return (
68 |
81 | );
82 | };
83 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/toast/CloseIcon.js:
--------------------------------------------------------------------------------
1 | export default function CloseIcon() {
2 | return (
3 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/toast/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | "/CloseIcon.js": require("./CloseIcon.js").default,
8 | ...sharedReactCode,
9 | },
10 | visibleFiles: ["/App.js", "/styles.css", "/CloseIcon.js"],
11 | };
12 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/toast/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="toast"][data-part="root"] {
2 | background: #fafaf9;
3 | border-radius: 0.75rem;
4 | border: solid 1px #e7e5e4;
5 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
6 | 0px 8px 16px rgba(48, 49, 51, 0.1);
7 | min-width: 20rem;
8 | padding: 12px;
9 | }
10 |
11 | .dark [data-scope="toast"][data-part="root"] {
12 | background: #111;
13 | border-color: #3e3e3e;
14 | box-shadow: 0px 0px 1px #0d0d0d, 0px 8px 16px rgba(13, 13, 13, 0.9);
15 | }
16 |
17 | [data-scope="toast"][data-part="group"] {
18 | padding: 12px;
19 | }
20 |
21 | [data-scope="toast"][data-part="title"] {
22 | font-weight: 600;
23 | line-height: 1.25rem;
24 | font-size: 0.875rem;
25 | }
26 |
27 | [data-scope="toast"][data-part="group"] {
28 | line-height: 1.25rem;
29 | font-size: 0.875rem;
30 | color: #737373;
31 | }
32 |
33 | .dark [data-scope="toast"][data-part="group"] {
34 | color: #8c8c8c;
35 | }
36 |
37 | .button {
38 | all: unset;
39 | align-items: center;
40 | appearance: none;
41 | border-radius: 0.5rem;
42 | cursor: pointer;
43 | display: inline-flex;
44 | font-weight: 500;
45 | justify-content: center;
46 | outline: none;
47 | position: relative;
48 | transition-property: color, background-color, border-color, outline-color,
49 | text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
50 | backdrop-filter;
51 | transition-duration: 100ms;
52 | transition-timing-function: ease-out;
53 | user-select: none;
54 | vertical-align: middle;
55 | white-space: nowrap;
56 | }
57 |
58 | .button_size__sm {
59 | height: 36px;
60 | min-width: 36px;
61 | padding-inline: 14px;
62 | line-height: 1.25rem;
63 | font-size: 0.875rem;
64 | }
65 |
66 | .button_size__md {
67 | height: 40px;
68 | min-width: 40px;
69 | padding-inline: 16px;
70 | line-height: 1.25rem;
71 | font-size: 0.875rem;
72 | }
73 |
74 | .button_link {
75 | color: #737373;
76 | background: transparent;
77 | height: auto;
78 | padding-inline: 0;
79 | }
80 |
81 | .dark .button_link {
82 | color: #8c8c8c;
83 | }
84 |
85 | .button_link:hover {
86 | color: #404040;
87 | }
88 |
89 | .dark .button_link:hover {
90 | color: #bfbfbf;
91 | }
92 |
93 | .button_primary {
94 | color: white;
95 | background-color: #60a5fa;
96 | }
97 |
98 | .button_primary:hover {
99 | background-color: #3b82f6;
100 | }
101 |
102 | .button_primary:focus {
103 | z-index: 1;
104 | --shadow: #eff6ff;
105 | box-shadow: 0 0 0 4px var(--shadow);
106 | }
107 |
108 | .dark .button_primary:focus {
109 | --shadow: #404040;
110 | }
111 |
112 | .button_tertiary {
113 | --fg-emphasized: #404040;
114 | --fg-default: #0d0d0d;
115 | --bg-subtle: #d9d9d9;
116 |
117 | padding-inline: 0px;
118 | background: transparent;
119 |
120 | color: var(--fg-emphasized);
121 | }
122 |
123 | .button_tertiary:focus {
124 | z-index: 1;
125 | --shadow: #d9d9d9;
126 | box-shadow: 0 0 0 4px var(--shadow);
127 | }
128 |
129 | .dark .button_tertiary:focus {
130 | --shadow: #262626;
131 | }
132 |
133 | .button_tertiary:hover {
134 | color: var(--fg-default);
135 | background: var(--bg-subtle);
136 | }
137 |
138 | .dark .button_tertiary {
139 | --fg-emphasized: #bfbfbf;
140 | --fg-default: white;
141 | --bg-subtle: #262626;
142 |
143 | color: #737373;
144 | }
145 |
146 | .close_button {
147 | position: absolute;
148 | top: 16px;
149 | right: 16px;
150 | color: #8c8c8c;
151 | }
152 |
153 | .close_button svg {
154 | font-size: 1.25rem;
155 | display: inline-flex;
156 | align-self: center;
157 | flex-shrink: 0;
158 | }
159 |
160 | .active,
161 | .dark .active {
162 | color: #a78bfa;
163 | }
164 |
165 | .stack {
166 | display: flex;
167 | flex-direction: column;
168 | gap: 4px;
169 | }
170 |
171 | .row {
172 | flex-direction: row;
173 | }
174 |
175 | .gap_12 {
176 | gap: 16px;
177 | }
178 |
179 | .gap_16 {
180 | gap: 16px;
181 | }
182 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/tooltip/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Tooltip,
3 | TooltipArrow,
4 | TooltipArrowTip,
5 | TooltipContent,
6 | TooltipPositioner,
7 | TooltipTrigger,
8 | } from "@ark-ui/react";
9 |
10 | import "./styles.css";
11 |
12 | export default function Page() {
13 | return (
14 |
15 |
16 | Hover me
17 |
18 |
19 |
20 |
21 |
22 | My Tooltip
23 |
24 |
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/tooltip/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedReactCode } from "component-data/react/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css": require("!!raw-loader!./styles.css").default,
6 | "/App.js": require("./App.js").default,
7 | ...sharedReactCode,
8 | },
9 | visibleFiles: ["/App.js", "/styles.css"],
10 | };
11 |
--------------------------------------------------------------------------------
/component-data/react/vanilla_css/scoped/tooltip/styles.css:
--------------------------------------------------------------------------------
1 | [data-scope="tooltip"][data-part="positioner"] {
2 | padding-block: 8px;
3 | padding-inline: 12px;
4 | border-radius: 0.75rem;
5 | box-shadow: 0px 0px 1px rgba(48, 49, 51, 0.05),
6 | 0px 8px 16px rgba(48, 49, 51, 0.1);
7 | background: #2563eb;
8 | color: #d9d9d9;
9 | }
10 |
11 | .dark [data-scope="tooltip"][data-part="positioner"] {
12 | box-shadow: 0px 0px 1px #0d0d0d, 0px 16px 24px rgba(13, 13, 13, 0.9);
13 | background: #d9d9d9;
14 | color: #2563eb;
15 | }
16 |
17 | [data-scope="tooltip"][data-part="trigger"] {
18 | cursor: pointer;
19 | }
20 |
21 | [data-scope="tooltip"][data-part="trigger"],
22 | [data-scope="tooltip"][data-part="content"] {
23 | font-weight: 500;
24 | font-size: 0.75rem;
25 | line-height: 1.125rem;
26 | }
27 |
28 | [data-scope="tooltip"][data-part="arrow"] {
29 | --arrow-size: 8px;
30 | --arrow-background: #2563eb;
31 | }
32 |
33 | .dark [data-scope="tooltip"][data-part="arrow"] {
34 | --arrow-background: #d9d9d9;
35 | }
36 |
--------------------------------------------------------------------------------
/component-data/solid/shared/404/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedSolidCode } from "component-data/solid/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/App.tsx": /*javascript*/ `
6 | const App = () => {
7 | return (
8 |
9 |
No example for this yet.
10 | Feel free to contribute
11 |
12 | );
13 | };
14 |
15 | export default App;
16 | `,
17 |
18 | "/styles.css":
19 | require("!!raw-loader!component-data/react/shared/404/styles.css")
20 | .default,
21 | ...sharedSolidCode,
22 | },
23 | visibleFiles: ["/App.tsx", "/styles.css"],
24 | };
25 |
--------------------------------------------------------------------------------
/component-data/solid/shared/wrapper/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + Solid
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/component-data/solid/shared/wrapper/index.ts:
--------------------------------------------------------------------------------
1 | export const sharedSolidCode = {
2 | "/index.css":
3 | require("!!raw-loader!component-data/react/shared/wrapper/index.css")
4 | .default,
5 |
6 | "/vite.config.ts": require("./vite.config.js").default,
7 | "/vite-env.d.ts": `/// `,
8 |
9 | "/tsconfig.json": `{
10 | "compilerOptions": {
11 | "target": "ESNext",
12 | "useDefineForClassFields": true,
13 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
14 | "allowJs": false,
15 | "skipLibCheck": true,
16 | "esModuleInterop": false,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "ESNext",
21 | "moduleResolution": "Node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "preserve",
26 | "jsxImportSource": "solid-js"
27 | },
28 | "include": ["src"],
29 | "references": [{ "path": "./tsconfig.node.json" }]
30 | }
31 | `,
32 | "/tsconfig.node.json": `{
33 | "compilerOptions": {
34 | "composite": true,
35 | "module": "ESNext",
36 | "moduleResolution": "Node",
37 | "allowSyntheticDefaultImports": true,
38 | "jsx": "preserve"
39 | },
40 | "include": ["vite.config.ts", "src/entry-server.tsx", "src/vite-env.d.ts"]
41 | }
42 | `,
43 |
44 | "/package.json": `{
45 | "name": "vite-project",
46 | "private": true,
47 | "version": "0.0.0",
48 | "type": "module",
49 | "scripts": {
50 | "start": "vite",
51 | "dev": "vite",
52 | "build": "vite build",
53 | "serve": "vite preview"
54 | },
55 | "dependencies": {
56 | "@ark-ui/solid": "latest",
57 | "solid-js": "^1.6.4",
58 | "@solid-primitives/script-loader": "latest"
59 | },
60 | "devDependencies": {
61 | "vite": "^4.0.0",
62 | "vite-plugin-solid": "^2.5.0"
63 | }
64 | }
65 | `,
66 |
67 | "/index.html": require("!!raw-loader!./index.html").default,
68 |
69 | "/index.tsx": /*javascript*/ `import { render } from "solid-js/web";
70 | import { createEffect } from "solid-js";
71 | import { createScriptLoader } from "@solid-primitives/script-loader";
72 |
73 | import App from "./App";
74 |
75 | import "./index.css";
76 |
77 | createScriptLoader({
78 | src: "https://cdn.tailwindcss.com",
79 | async onLoad() {
80 | tailwind.config = {
81 | darkMode: "class"
82 | }
83 | },
84 | });
85 |
86 | function ColorModeScript() {
87 | createEffect(() => {
88 | window.parent.postMessage({ action: "getColorMode" }, "*");
89 | window.addEventListener("message", function (event) {
90 | if (event.data.colorMode) {
91 | switch (event.data.colorMode) {
92 | case "light":
93 | document.body.classList.add("light");
94 | document.body.classList.remove("dark");
95 | break;
96 |
97 | case "dark":
98 | document.body.classList.add("dark");
99 | document.body.classList.remove("light");
100 | break;
101 |
102 | default:
103 | break;
104 | }
105 | }
106 | });
107 | });
108 |
109 | return null;
110 | }
111 |
112 | render(
113 | () => (
114 | <>
115 |
116 |
117 | >
118 | ),
119 | document.getElementById("root") as HTMLElement
120 | );
121 | `,
122 | };
123 |
--------------------------------------------------------------------------------
/component-data/solid/shared/wrapper/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import solidPlugin from "vite-plugin-solid";
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [solidPlugin()],
7 | server: {
8 | port: 3000,
9 | },
10 | build: {
11 | target: "esnext",
12 | },
13 | });
14 |
--------------------------------------------------------------------------------
/component-data/solid/tailwind/inline/checkbox/index.ts:
--------------------------------------------------------------------------------
1 | import { styles } from "component-data/react/tailwind/inline/checkbox/styles";
2 | import { checkbox } from "component-data/solid/vanilla_css/scoped/checkbox";
3 | import { tailwindInlineTransform } from "component-data/utils";
4 |
5 | export default tailwindInlineTransform(checkbox, styles);
6 |
--------------------------------------------------------------------------------
/component-data/solid/vanilla_css/scoped/accordion/AccordionIcon.js:
--------------------------------------------------------------------------------
1 | const AccordionIcon = (props) => {
2 | const iconStyles = {
3 | transform: props.isOpen ? "rotate(-180deg)" : undefined,
4 | transition: "transform 0.2s",
5 | transformOrigin: "center",
6 | };
7 | return (
8 |
24 | );
25 | };
26 |
27 | export default AccordionIcon;
28 |
--------------------------------------------------------------------------------
/component-data/solid/vanilla_css/scoped/accordion/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Accordion,
3 | AccordionContent,
4 | AccordionItem,
5 | AccordionTrigger,
6 | } from "@ark-ui/solid";
7 | import { For } from "solid-js";
8 |
9 | import "./styles.css";
10 |
11 | const items = ["React", "Solid", "Vue"];
12 |
13 | export default function Page() {
14 | return (
15 |
16 |
17 | {(item) => (
18 |
19 | {(state) => (
20 | <>
21 |
22 |
27 |
28 |
29 | Pudding donut gummies chupa chups oat cake marzipan biscuit
30 | tart. Dessert macaroon ice cream bonbon jelly. Jelly topping
31 | tiramisu halvah lollipop.
32 |
33 | >
34 | )}
35 |
36 | )}
37 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/component-data/solid/vanilla_css/scoped/accordion/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedSolidCode } from "component-data/solid/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/styles.css":
6 | require("!!raw-loader!component-data/react/vanilla_css/scoped/accordion/styles.css")
7 | .default,
8 | "/App.tsx": require("./App.js").default,
9 | "/AccordionIcon.tsx": require("./AccordionIcon.js").default,
10 | ...sharedSolidCode,
11 | },
12 | visibleFiles: ["/App.tsx", "/styles.css", "/AccordionIcon.tsx"],
13 | };
14 |
--------------------------------------------------------------------------------
/component-data/solid/vanilla_css/scoped/checkbox/App.js:
--------------------------------------------------------------------------------
1 | import {
2 | Checkbox,
3 | CheckboxControl,
4 | CheckboxInput,
5 | CheckboxLabel,
6 | } from "@ark-ui/solid";
7 | import { createSignal } from "solid-js";
8 |
9 | import CheckIcon from "./CheckIcon";
10 | import MinusIcon from "./MinusIcon";
11 | import "./styles.css";
12 |
13 | export default function Page() {
14 | const [checkedItems, setCheckedItems] = createSignal([false, false]);
15 |
16 | const allChecked = () => checkedItems().every(Boolean);
17 | const isIndeterminate = () => checkedItems().some(Boolean) && !allChecked();
18 |
19 | return (
20 | <>
21 | setCheckedItems([e.checked, e.checked])}
26 | >
27 | {(state) => (
28 | <>
29 |
30 |
31 | {state().isChecked && }
32 | {state().isIndeterminate && }
33 |
34 | Parent Checkbox
35 | >
36 | )}
37 |
38 |
39 | setCheckedItems([e.checked, checkedItems()[1]])}
43 | >
44 | {(state) => (
45 | <>
46 |
47 |
48 | {state().isChecked && }
49 |
50 |
51 | Child Checkbox 1
52 |
53 | >
54 | )}
55 |
56 | setCheckedItems([checkedItems()[0], e.checked])}
60 | >
61 | {(state) => (
62 | <>
63 |
64 |
65 | {state().isChecked && }
66 |
67 |
68 | Child Checkbox 2
69 |
70 | >
71 | )}
72 |
73 |
74 | >
75 | );
76 | }
77 |
--------------------------------------------------------------------------------
/component-data/solid/vanilla_css/scoped/checkbox/CheckIcon.js:
--------------------------------------------------------------------------------
1 | export default function CheckIcon() {
2 | return (
3 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/component-data/solid/vanilla_css/scoped/checkbox/MinusIcon.js:
--------------------------------------------------------------------------------
1 | export default function MinusIcon() {
2 | return (
3 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/component-data/solid/vanilla_css/scoped/checkbox/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedSolidCode } from "component-data/solid/shared/wrapper";
2 | import { vanillaScopedTransform } from "component-data/utils";
3 |
4 | export const checkbox = {
5 | files: {
6 | "/styles.css":
7 | require("!!raw-loader!component-data/react/vanilla_css/scoped/checkbox/styles.css")
8 | .default,
9 | "/App.tsx": require("./App.js").default,
10 | "/CheckIcon.tsx": require("./CheckIcon.js").default,
11 | "/MinusIcon.tsx": require("./MinusIcon.js").default,
12 | ...sharedSolidCode,
13 | },
14 | visibleFiles: ["/App.tsx", "/styles.css", "/CheckIcon.tsx", "/MinusIcon.tsx"],
15 | };
16 |
17 | export default vanillaScopedTransform(checkbox);
18 |
--------------------------------------------------------------------------------
/component-data/utils.ts:
--------------------------------------------------------------------------------
1 | import { ComponentSetup } from "utils/component-setup";
2 |
3 | export const replaceClassnames = (
4 | code: string,
5 | styles: Record
6 | ) => {
7 | Object.entries(styles).forEach(([key, classes]) => {
8 | if (!code.includes(key)) return code;
9 |
10 | if (!classes) {
11 | code = code.replaceAll(
12 | new RegExp(`\\s(className=|class=)(['"])(${key})*\\2`, "g"),
13 | ""
14 | );
15 | }
16 |
17 | code = code.replaceAll(`"${key}"`, classes);
18 | });
19 |
20 | return code;
21 | };
22 |
23 | const stripExternalCSS = (code: string) =>
24 | code.replace('import "./styles.css";', "");
25 |
26 | const stripClassnames = (code: string) => {
27 | const regex = /class(?:Name)?\s*=\s*['"](\w+Styles)['"]/g;
28 |
29 | return code.replace(regex, (match, cls) => {
30 | if (cls.endsWith("Styles")) {
31 | return "";
32 | } else {
33 | return match;
34 | }
35 | });
36 | };
37 | export const vanillaScopedTransform = (setup: ComponentSetup) => {
38 | return {
39 | ...setup,
40 | files: Object.entries(setup.files).reduce(
41 | (acc, [fileName, code]) => ({
42 | ...acc,
43 | [fileName]: stripClassnames(code),
44 | }),
45 | {}
46 | ),
47 | };
48 | };
49 |
50 | export const tailwindInlineTransform = (
51 | setup: ComponentSetup,
52 | styles: Record = {}
53 | ): ComponentSetup => {
54 | return {
55 | ...setup,
56 | files: Object.entries(setup.files).reduce(
57 | (acc, [fileName, code]) => ({
58 | ...acc,
59 | [fileName]: replaceClassnames(stripExternalCSS(code), styles),
60 | }),
61 | {}
62 | ),
63 | visibleFiles: setup.visibleFiles.filter((f) => !f.includes("styles.css")),
64 | };
65 | };
66 |
--------------------------------------------------------------------------------
/component-data/vue/shared/404/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedVueCode } from "component-data/vue/shared/wrapper";
2 |
3 | export default {
4 | files: {
5 | "/App.vue": /*html*/ `
6 |
7 |
No example for this yet.
8 | Feel free to contribute
9 |
10 | `,
11 |
12 | "/styles.css":
13 | require("!!raw-loader!component-data/react/shared/404/styles.css")
14 | .default,
15 | ...sharedVueCode,
16 | },
17 | visibleFiles: ["/App.vue", "/styles.css"],
18 | };
19 |
--------------------------------------------------------------------------------
/component-data/vue/shared/wrapper/index.ts:
--------------------------------------------------------------------------------
1 | export const sharedVueCode = {
2 | "/index.css":
3 | require("!!raw-loader!component-data/react/shared/wrapper/index.css")
4 | .default,
5 |
6 | "/public/index.html": /*html*/ `
7 |
8 |
9 |
10 |
11 |
12 | codesandbox
13 |
14 |
15 |
21 |
22 |
23 |
24 |
25 | `,
26 |
27 | "index.js": `import { createApp } from 'vue'
28 | import Main from './Main.vue'
29 | import "./index.css";
30 |
31 | createApp(Main).mount('#root')
32 | `,
33 |
34 | "/Main.vue": `
72 |
73 |
74 |
75 |
76 | `,
77 |
78 | "package.json": `{
79 | "name": "vue3",
80 | "version": "0.1.0",
81 | "private": true,
82 | "main": "/index.js",
83 | "scripts": {
84 | "serve": "vue-cli-service serve",
85 | "build": "vue-cli-service build"
86 | },
87 | "dependencies": {
88 | "core-js": "^3.26.1",
89 | "vue": "^3.2.45",
90 | "@ark-ui/vue": "latest",
91 | "@vueuse/core": "latest"
92 | },
93 | "devDependencies": {
94 | "@vue/cli-plugin-babel": "^5.0.8",
95 | "@vue/cli-service": "^5.0.8"
96 | }
97 | }`,
98 | };
99 |
--------------------------------------------------------------------------------
/component-data/vue/tailwind/inline/checkbox/index.ts:
--------------------------------------------------------------------------------
1 | import { styles } from "component-data/react/tailwind/inline/checkbox/styles";
2 | import { tailwindInlineTransform } from "component-data/utils";
3 | import { checkbox } from "component-data/vue/vanilla_css/scoped/checkbox";
4 |
5 | export default tailwindInlineTransform(checkbox, styles);
6 |
--------------------------------------------------------------------------------
/component-data/vue/vanilla_css/scoped/checkbox/App.vue:
--------------------------------------------------------------------------------
1 |
20 |
21 |
22 | {
26 | checkedItems[0] = checked;
27 | checkedItems[1] = checked;
28 | }
29 | "
30 | v-model:checked="allChecked"
31 | v-model:indeterminate="someChecked"
32 | v-slot="{ isChecked, isIndeterminate }"
33 | >
34 |
35 |
36 |
37 |
38 |
39 | Parent Checkbox
40 |
41 |
42 |
47 |
48 |
49 |
50 |
51 | Child Checkbox 1
52 |
53 |
58 |
59 |
60 |
61 |
62 | Child Checkbox 2
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/component-data/vue/vanilla_css/scoped/checkbox/CheckIcon.vue:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
--------------------------------------------------------------------------------
/component-data/vue/vanilla_css/scoped/checkbox/MinusIcon.vue:
--------------------------------------------------------------------------------
1 |
2 |
17 |
--------------------------------------------------------------------------------
/component-data/vue/vanilla_css/scoped/checkbox/index.ts:
--------------------------------------------------------------------------------
1 | import { vanillaScopedTransform } from "component-data/utils";
2 | import { sharedVueCode } from "component-data/vue/shared/wrapper";
3 |
4 | export const checkbox = {
5 | files: {
6 | "/styles.css":
7 | require("!!raw-loader!component-data/react/vanilla_css/scoped/checkbox/styles.css")
8 | .default,
9 | "/App.vue": require("./App.vue").default,
10 | "/CheckIcon.vue": require("./CheckIcon.vue").default,
11 | "/MinusIcon.vue": require("./MinusIcon.vue").default,
12 | ...sharedVueCode,
13 | },
14 | visibleFiles: ["/App.vue", "/styles.css", "/CheckIcon.vue", "/MinusIcon.vue"],
15 | };
16 |
17 | export default vanillaScopedTransform(checkbox);
18 |
--------------------------------------------------------------------------------
/component-data/vue/vanilla_css/scoped/popover/App.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
Favorite Cake
30 |
31 | Dessert jelly beans pudding chocolate pie pastry danish chocolate
32 | pie.
33 |
34 |
35 |
36 |
37 |
38 |
41 |
42 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/component-data/vue/vanilla_css/scoped/popover/index.ts:
--------------------------------------------------------------------------------
1 | import { vanillaScopedTransform } from "component-data/utils";
2 | import { sharedVueCode } from "component-data/vue/shared/wrapper";
3 |
4 | export const popover = {
5 | files: {
6 | "/styles.css":
7 | require("!!raw-loader!component-data/react/vanilla_css/scoped/popover/styles.css")
8 | .default,
9 | "/App.vue": require("./App.vue").default,
10 | ...sharedVueCode,
11 | },
12 | visibleFiles: ["/App.vue", "/styles.css"],
13 | };
14 |
15 | export default vanillaScopedTransform(popover);
16 |
--------------------------------------------------------------------------------
/component-data/vue/vanilla_css/scoped/select/App.vue:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
42 |
43 |
--------------------------------------------------------------------------------
/component-data/vue/vanilla_css/scoped/select/SelectIcon.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
30 |
31 |
--------------------------------------------------------------------------------
/component-data/vue/vanilla_css/scoped/select/index.ts:
--------------------------------------------------------------------------------
1 | import { vanillaScopedTransform } from "component-data/utils";
2 | import { sharedVueCode } from "component-data/vue/shared/wrapper";
3 |
4 | export const select = {
5 | files: {
6 | "/styles.css":
7 | require("!!raw-loader!component-data/react/vanilla_css/scoped/select/styles.css")
8 | .default,
9 | "/App.vue": require("./App.vue").default,
10 | "/SelectIcon.vue": require("./SelectIcon.vue").default,
11 | ...sharedVueCode,
12 | },
13 | visibleFiles: ["/App.vue", "/styles.css", "/SelectIcon.vue"],
14 | };
15 |
16 | export default vanillaScopedTransform(select);
17 |
--------------------------------------------------------------------------------
/components/CloseButton.tsx:
--------------------------------------------------------------------------------
1 | import { FiX } from "react-icons/fi";
2 |
3 | import { IconButton, IconButtonProps } from "./IconButton";
4 |
5 | export const CloseButton = (props: IconButtonProps) => (
6 | }
11 | variant="tertiary"
12 | size="xs"
13 | {...props}
14 | />
15 | );
16 |
--------------------------------------------------------------------------------
/components/CodeEditor.tsx:
--------------------------------------------------------------------------------
1 | import { SandpackCodeEditor } from "@codesandbox/sandpack-react";
2 |
3 | import { Flex } from "design-system/jsx";
4 |
5 | import { EditorTabs } from "components/EditorTabs";
6 |
7 | import { ComponentId } from "utils/types";
8 |
9 | type CodeEditorProps = {
10 | componentId: ComponentId;
11 | };
12 | export function CodeEditor(props: CodeEditorProps) {
13 | return (
14 | <>
15 |
16 |
17 |
23 |
24 | >
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/components/ColorModeButton.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { Expand } from "@theme-toggles/react";
4 | import "@theme-toggles/react/css/Expand.css";
5 | import { useIsClient } from "usehooks-ts";
6 |
7 | import { css } from "design-system/css/css";
8 | import { cx } from "design-system/css/cx";
9 | import { button } from "design-system/recipes";
10 |
11 | import { useColorMode } from "utils/useColorMode";
12 |
13 | export const ColorModeButton = () => {
14 | const { toggle, colorMode } = useColorMode();
15 |
16 | const isClient = useIsClient();
17 | // prevent false positive for server-side rendering
18 | if (!isClient) {
19 | return null;
20 | }
21 | return (
22 |
35 | );
36 | };
37 |
--------------------------------------------------------------------------------
/components/ColorModeScript.tsx:
--------------------------------------------------------------------------------
1 | import { colorModeLocalStorageKey } from "utils/useColorMode";
2 |
3 | /**
4 | * This script is used to set the color mode on the initial page load.
5 | * It runs before hydration and prevents a flash of maybe unwanted light mode.
6 | */
7 | export const ColorModeScript = () => {
8 | const colorModeScript =
9 | // language=javascript
10 | `if (JSON.parse(window.localStorage.getItem('${colorModeLocalStorageKey}')) === 'dark') {
11 | document.documentElement.classList.add('dark')
12 | }`;
13 | return ;
14 | };
15 |
--------------------------------------------------------------------------------
/components/ComponentControls/FrameworkSwitch.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | Portal,
3 | Select,
4 | SelectContent,
5 | SelectOption,
6 | SelectPositioner,
7 | SelectTrigger,
8 | } from "@ark-ui/react";
9 | import { Fragment } from "react";
10 |
11 | import { css, cx } from "design-system/css";
12 | import { select } from "design-system/recipes";
13 |
14 | import { ComponentControl } from "components/ComponentControls";
15 |
16 | import { FRAMEWORKS } from "utils/component-config/constants";
17 | import { useComponentConfig } from "utils/useComponentConfig";
18 |
19 | import { SelectIcon } from "../SelectIcon";
20 |
21 | export function FrameworkSwitch(props: ComponentControl) {
22 | const Wrapper = props.norPortal ? Fragment : Portal;
23 |
24 | const { framework } = useComponentConfig();
25 |
26 | return (
27 |
59 | );
60 | }
61 |
--------------------------------------------------------------------------------
/components/ComponentControls/Navigation/Search.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | Combobox,
3 | ComboboxContent,
4 | ComboboxControl,
5 | ComboboxInput,
6 | ComboboxOption,
7 | } from "@ark-ui/react";
8 | import { useRouter } from "next/navigation";
9 | import { MutableRefObject } from "react";
10 | import { CgHashtag } from "react-icons/cg";
11 | import { FaChevronRight } from "react-icons/fa";
12 |
13 | import { css } from "design-system/css/css";
14 | import { cx } from "design-system/css/cx";
15 | import { Flex, panda } from "design-system/jsx";
16 | import { input } from "design-system/recipes";
17 |
18 | import { LinkBox, LinkOverlay } from "components/LinkOverlay";
19 |
20 | import { useComponentsSearch } from "utils/useComponentsSearch";
21 |
22 | type SearchProps = ReturnType & {
23 | inputRef: MutableRefObject;
24 | uriQuery: string;
25 | closeDialog: () => void;
26 | };
27 |
28 | export function Search(props: SearchProps) {
29 | const {
30 | inputRef,
31 | uriQuery,
32 | query,
33 | setQuery,
34 | filteredComponents,
35 | emptyResult,
36 | closeDialog,
37 | } = props;
38 |
39 | const router = useRouter();
40 |
41 | return (
42 | <>
43 | {
48 | setQuery(value);
49 | }}
50 | onSelect={({ value }) => {
51 | router.push(`${value}${uriQuery}`);
52 | closeDialog();
53 | }}
54 | className={css({
55 | width: "full",
56 | })}
57 | >
58 | {({ isOpen }) => (
59 | <>
60 |
61 | {
66 | inputRef.current.click();
67 | }}
68 | />
69 |
70 |
71 | {isOpen ? (
72 |
85 | {filteredComponents.map((item, index) => (
86 |
97 |
116 |
131 |
132 |
133 |
139 | {item.label}
140 |
141 |
142 |
152 |
153 |
154 |
155 |
156 | ))}
157 | {emptyResult ? (
158 |
159 | Can't find that component. Perharps an invention{" "}
160 | of yours? 🧐
161 |
162 | ) : null}
163 |
164 | ) : null}
165 | >
166 | )}
167 |
168 | >
169 | );
170 | }
171 |
--------------------------------------------------------------------------------
/components/ComponentControls/Navigation/index.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | Dialog,
3 | DialogBackdrop,
4 | DialogCloseTrigger,
5 | DialogContainer,
6 | DialogContent,
7 | DialogDescription,
8 | DialogTitle,
9 | DialogTrigger,
10 | Portal,
11 | } from "@ark-ui/react";
12 | import { useRef, useState } from "react";
13 | import { FiMenu } from "react-icons/fi";
14 |
15 | import { css } from "design-system/css/css";
16 | import { cx } from "design-system/css/cx";
17 | import { Flex, Stack, panda } from "design-system/jsx";
18 | import { dialog } from "design-system/recipes";
19 |
20 | import { ComponentControlsProps } from "components/ComponentControls";
21 | import { FrameworkSwitch } from "components/ComponentControls/FrameworkSwitch";
22 | import { Search } from "components/ComponentControls/Navigation/Search";
23 | import { StyleSolutionSwitch } from "components/ComponentControls/StyleSolutionSwitch";
24 | import { StyleTypeSwitch } from "components/ComponentControls/StyleTypeSwitch";
25 | import { IconButton } from "components/IconButton";
26 |
27 | import { setComponentConfig } from "utils/component-config";
28 | import {
29 | Framework,
30 | StyleSolution,
31 | StyleType,
32 | } from "utils/component-config/constants";
33 | import { useComponentConfig, useQueryString } from "utils/useComponentConfig";
34 | import { useComponentsSearch } from "utils/useComponentsSearch";
35 |
36 | import { CloseButton } from "../../CloseButton";
37 |
38 | const dialogClassName = dialog();
39 |
40 | export function Navigation(props: ComponentControlsProps) {
41 | const { component } = props;
42 |
43 | const inputRef = useRef(null);
44 |
45 | const { framework, styleSolution, styleType } = useComponentConfig();
46 | const [tempConfig, setTempConfig] = useState({
47 | framework,
48 | styleSolution,
49 | styleType,
50 | });
51 |
52 | const uriQuery = useQueryString(tempConfig);
53 |
54 | const componentSearch = useComponentsSearch();
55 |
56 | const onDialogClose = () => {
57 | componentSearch.setQuery("");
58 | };
59 |
60 | return (
61 |
165 | );
166 | }
167 |
--------------------------------------------------------------------------------
/components/ComponentControls/StyleSolutionSwitch.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | Portal,
3 | Select,
4 | SelectContent,
5 | SelectOption,
6 | SelectPositioner,
7 | SelectTrigger,
8 | } from "@ark-ui/react";
9 | import { Fragment } from "react";
10 |
11 | import { css, cx } from "design-system/css";
12 | import { select } from "design-system/recipes";
13 |
14 | import { ComponentControl } from "components/ComponentControls";
15 |
16 | import { STYLE_SOLUTIONS } from "utils/component-config/constants";
17 | import { useComponentConfig } from "utils/useComponentConfig";
18 |
19 | import { SelectIcon } from "../SelectIcon";
20 |
21 | export function StyleSolutionSwitch(props: ComponentControl) {
22 | const Wrapper = props.norPortal ? Fragment : Portal;
23 | const { styleSolution } = useComponentConfig();
24 |
25 | return (
26 |
58 | );
59 | }
60 |
--------------------------------------------------------------------------------
/components/ComponentControls/StyleTypeSwitch.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | Portal,
3 | Select,
4 | SelectContent,
5 | SelectOption,
6 | SelectPositioner,
7 | SelectTrigger,
8 | } from "@ark-ui/react";
9 | import { Fragment } from "react";
10 |
11 | import { css, cx } from "design-system/css";
12 | import { select } from "design-system/recipes";
13 |
14 | import { ComponentControl } from "components/ComponentControls";
15 |
16 | import { STYLE_SOLUTIONS } from "utils/component-config/constants";
17 | import { useComponentConfig } from "utils/useComponentConfig";
18 |
19 | import { SelectIcon } from "../SelectIcon";
20 |
21 | export function StyleTypeSwitch(props: ComponentControl) {
22 | const Wrapper = props.norPortal ? Fragment : Portal;
23 |
24 | const { styleType: currentStyleType, styleSolution: currentStyleSolution } =
25 | useComponentConfig();
26 |
27 | const styleSolution = props.styleSolution ?? currentStyleSolution;
28 | const styleType = props.styleType ?? currentStyleType;
29 |
30 | const styleTypeOption = STYLE_SOLUTIONS[styleSolution].types.find(
31 | (opt) => opt.value === styleType
32 | );
33 | return (
34 |
66 | );
67 | }
68 |
--------------------------------------------------------------------------------
/components/ComponentControls/index.tsx:
--------------------------------------------------------------------------------
1 | import { SelectProps } from "@ark-ui/react";
2 |
3 | import { Flex } from "design-system/jsx";
4 |
5 | import { Navigation } from "components/ComponentControls/Navigation";
6 |
7 | import {
8 | Framework,
9 | StyleSolution,
10 | StyleType,
11 | } from "utils/component-config/constants";
12 | import { Component } from "utils/types";
13 | import { useComponentConfig } from "utils/useComponentConfig";
14 |
15 | import { FrameworkSwitch } from "../ComponentControls/FrameworkSwitch";
16 | import { StyleSolutionSwitch } from "../ComponentControls/StyleSolutionSwitch";
17 | import { StyleTypeSwitch } from "../ComponentControls/StyleTypeSwitch";
18 |
19 | export type ComponentControlsProps = {
20 | component: Component;
21 | };
22 |
23 | export type ComponentControl = {
24 | onChange: SelectProps["onChange"];
25 | norPortal?: boolean;
26 | framework?: Framework;
27 | styleSolution?: StyleSolution;
28 | styleType?: StyleType;
29 | };
30 | export function ComponentControls(props: ComponentControlsProps) {
31 | const { setComponentConfig } = useComponentConfig();
32 |
33 | return (
34 |
41 |
42 |
43 |
44 | {
46 | setComponentConfig("framework", opt?.value as Framework);
47 | }}
48 | />
49 | {
51 | setComponentConfig("styleSolution", opt?.value as StyleSolution);
52 | }}
53 | />
54 | {
56 | setComponentConfig("styleType", opt?.value as StyleType);
57 | }}
58 | />
59 |
60 |
61 | );
62 | }
63 |
--------------------------------------------------------------------------------
/components/CopyCodeButton.tsx:
--------------------------------------------------------------------------------
1 | import { useActiveCode, useSandpack } from "@codesandbox/sandpack-react";
2 | import { HiOutlineClipboardList } from "react-icons/hi";
3 | import { useCopyToClipboard } from "usehooks-ts";
4 |
5 | import { IconButton } from "components/IconButton";
6 |
7 | export const CopyCodeButton = () => {
8 | const { code } = useActiveCode();
9 | const [, copy] = useCopyToClipboard();
10 | const { sandpack } = useSandpack();
11 |
12 | const title = `Copy ${sandpack.activeFile.split("/")[1]} content`;
13 |
14 | return (
15 | copy(code)}
19 | icon={}
20 | variant="tertiary"
21 | size="xs"
22 | />
23 | );
24 | };
25 |
--------------------------------------------------------------------------------
/components/EditorTabs.tsx:
--------------------------------------------------------------------------------
1 | import { useSandpack } from "@codesandbox/sandpack-react";
2 |
3 | import { Flex, panda } from "design-system/jsx";
4 |
5 | import { CopyCodeButton } from "components/CopyCodeButton";
6 | import { FormatCodeButton } from "components/FormatCodeButton";
7 | import { OpenInCodesandboxButton } from "components/OpenInCodesandboxButton";
8 |
9 | import { ComponentId } from "utils/types";
10 | import { useComponentSetup } from "utils/useComponentSetup";
11 |
12 | type EditorTabsProps = {
13 | componentId: ComponentId;
14 | };
15 | export const EditorTabs = ({ componentId }: EditorTabsProps) => {
16 | const componentDetails = useComponentSetup(componentId as any);
17 |
18 | const { sandpack } = useSandpack();
19 | const { activeFile, setActiveFile } = sandpack;
20 |
21 | return (
22 |
27 |
37 | {componentDetails.visibleFiles.map((fileName) => (
38 | setActiveFile(fileName)}
41 | aria-selected={fileName === activeFile}
42 | data-active={fileName === activeFile ? "" : undefined}
43 | color={{
44 | base: "var(--sp-colors-clickable)",
45 | _hover: "var(--sp-colors-hover)",
46 | _active: "var(--sp-colors-accent)",
47 | }}
48 | padding="0 var(--sp-space-2)"
49 | height="var(--sp-layout-headerHeight)"
50 | whiteSpace="nowrap"
51 | appearance="none"
52 | outline="none"
53 | display="flex"
54 | alignItems="center"
55 | background="transparent"
56 | transition="color var(--sp-transitions-default), background var(--sp-transitions-default)"
57 | cursor="pointer"
58 | border="0px"
59 | textDecoration="none"
60 | role="tab"
61 | title={fileName}
62 | type="button"
63 | >
64 | {fileName.split("/")[1]}
65 |
66 | ))}
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | );
76 | };
77 |
--------------------------------------------------------------------------------
/components/FormatCodeButton.tsx:
--------------------------------------------------------------------------------
1 | import { useActiveCode, useSandpack } from "@codesandbox/sandpack-react";
2 | import { ImMagicWand } from "react-icons/im";
3 |
4 | import { IconButton } from "components/IconButton";
5 |
6 | import { formatCode } from "utils/component-setup";
7 |
8 | export const FormatCodeButton = () => {
9 | const { code, updateCode } = useActiveCode();
10 | const { sandpack } = useSandpack();
11 |
12 | const runPrettier = () => {
13 | const formattedCode = formatCode(code, sandpack.activeFile);
14 | updateCode(formattedCode);
15 | };
16 |
17 | return (
18 | }
23 | variant="tertiary"
24 | size="xs"
25 | />
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/components/IconButton.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cloneElement, isValidElement } from "react";
4 |
5 | import { css, cx } from "design-system/css";
6 | import { type HTMLPandaProps, panda } from "design-system/jsx";
7 | import { type ButtonVariants, button } from "design-system/recipes";
8 |
9 | export type IconButtonProps = HTMLPandaProps<"button"> &
10 | ButtonVariants & { icon?: React.ReactElement; "aria-label": string };
11 |
12 | export const IconButton = (props: IconButtonProps) => {
13 | const { icon, variant, size, children, ...rest } = props;
14 |
15 | const element = icon || children;
16 | const _children = isValidElement(element)
17 | ? cloneElement(element, {
18 | // @ts-expect-error typings are wrong
19 | "aria-hidden": true,
20 | "data-scope": "button",
21 | "data-part": "icon",
22 | focusable: false,
23 | })
24 | : null;
25 |
26 | return (
27 |
33 | {_children}
34 |
35 | );
36 | };
37 |
--------------------------------------------------------------------------------
/components/LinkOverlay.tsx:
--------------------------------------------------------------------------------
1 | import Link, { LinkProps } from "next/link";
2 | import { forwardRef } from "react";
3 |
4 | import { css, cx } from "design-system/css";
5 | import { HTMLPandaProps, panda } from "design-system/jsx";
6 |
7 | const PandaLink = panda(Link);
8 |
9 | export interface LinkOverlayProps extends Omit, "href"> {
10 | href: LinkProps["href"];
11 | /**
12 | * If `true`, the link will open in new tab
13 | *
14 | * @default false
15 | */
16 | isExternal?: boolean;
17 | }
18 |
19 | export const LinkOverlay = forwardRef(
20 | function LinkOverlay(props, ref) {
21 | const { isExternal, target, rel, className, ...rest } = props;
22 | return (
23 |
48 | );
49 | }
50 | );
51 |
52 | export interface LinkBoxProps extends HTMLPandaProps<"div"> {}
53 |
54 | /**
55 | * `LinkBox` is used to wrap content areas within a link while ensuring semantic html
56 | *
57 | * @see Resources https://www.sarasoueidan.com/blog/nested-links
58 | */
59 | export const LinkBox = forwardRef(
60 | function LinkBox(props, ref) {
61 | const { className, ...rest } = props;
62 |
63 | return (
64 |
79 | );
80 | }
81 | );
82 |
--------------------------------------------------------------------------------
/components/Navbar.tsx:
--------------------------------------------------------------------------------
1 | import { BsGithub } from "react-icons/bs";
2 |
3 | import { Flex, panda } from "design-system/jsx";
4 |
5 | import { IconButton } from "components/IconButton";
6 |
7 | import { ColorModeButton } from "./ColorModeButton";
8 |
9 | export function Navbar() {
10 | return (
11 |
18 |
19 | Arkxamples
20 |
21 |
22 |
23 | }
27 | variant="tertiary"
28 | size="xs"
29 | />
30 |
31 |
32 |
33 |
34 | );
35 | }
36 |
--------------------------------------------------------------------------------
/components/OpenInCodesandboxButton.tsx:
--------------------------------------------------------------------------------
1 | import { UnstyledOpenInCodeSandboxButton } from "@codesandbox/sandpack-react";
2 | import { RxCodesandboxLogo } from "react-icons/rx";
3 |
4 | import { css, cx } from "design-system/css";
5 | import { button } from "design-system/recipes";
6 |
7 | export const OpenInCodesandboxButton = () => {
8 | return (
9 |
18 |
23 |
24 | );
25 | };
26 |
--------------------------------------------------------------------------------
/components/SelectIcon.tsx:
--------------------------------------------------------------------------------
1 | import { FiChevronDown } from "react-icons/fi";
2 |
3 | export const SelectIcon = (props: { isOpen: boolean }) => {
4 | const iconStyles = {
5 | transform: props.isOpen ? "rotate(-180deg)" : undefined,
6 | transition: "transform 0.2s",
7 | transformOrigin: "center",
8 | };
9 | return ;
10 | };
11 |
--------------------------------------------------------------------------------
/components/button.tsx:
--------------------------------------------------------------------------------
1 | import { css } from "design-system/css";
2 |
3 | export function Button({ children, css: cssProp }) {
4 | return (
5 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/components/card.tsx:
--------------------------------------------------------------------------------
1 | import { css } from "design-system/css";
2 |
3 | export function Card({ children }) {
4 | return (
5 |
16 | {children}
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/index.css:
--------------------------------------------------------------------------------
1 | @layer reset, base, tokens, recipes, utilities;
2 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | swcMinify: true,
5 | experimental: {
6 | appDir: true,
7 | externalDir: true,
8 | },
9 | webpack: (config) => {
10 | config.module.rules.push({
11 | test: /component-data.*\.vue/,
12 | use: "raw-loader",
13 | });
14 |
15 | config.module.rules.push({
16 | test: /component-data.*\.html/,
17 | use: "raw-loader",
18 | });
19 |
20 | config.module.rules.push({
21 | test: /component-data.*\.js/,
22 | use: "raw-loader",
23 | });
24 |
25 | return config;
26 | },
27 | };
28 |
29 | module.exports = nextConfig;
30 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sandbox-next-js",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "prepare": "panda",
7 | "dev": "rm -rf .next && next dev",
8 | "build": "next build",
9 | "start": "next start",
10 | "lint": "next lint",
11 | "css": "PANDA_DEBUG=* panda",
12 | "css:dev": "PANDA_DEBUG=* panda --watch",
13 | "format": "prettier --write \"./**/*.{ts,tsx,json,js}\""
14 | },
15 | "dependencies": {
16 | "next": "13.2.4",
17 | "react": "18.2.0",
18 | "react-dom": "18.2.0"
19 | },
20 | "devDependencies": {
21 | "@ark-ui/react": "^0.2.0",
22 | "@ark-ui/solid": "latest",
23 | "@ark-ui/vue": "latest",
24 | "@codesandbox/sandpack-react": "^2.1.9",
25 | "@pandacss/dev": "0.0.0-dev-20230213064154",
26 | "@theme-toggles/react": "^4.1.0",
27 | "@trivago/prettier-plugin-sort-imports": "^4.1.1",
28 | "@types/node": "18.15.3",
29 | "@types/prettier": "^2.7.2",
30 | "@types/react": "18.0.28",
31 | "@types/react-dom": "^18.0.11",
32 | "eslint": "8.36.0",
33 | "eslint-config-next": "13.2.4",
34 | "prettier": "^2.8.5",
35 | "raw-loader": "^4.0.2",
36 | "react-icons": "^4.8.0",
37 | "solid-js": "^1.6.15",
38 | "typescript": "5.0.2",
39 | "usehooks-ts": "^2.9.1"
40 | }
41 | }
--------------------------------------------------------------------------------
/panda.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "@pandacss/dev";
2 |
3 | import { globalCss } from "./theme/global-css";
4 | import { recipes } from "./theme/recipes";
5 | import { textStyles } from "./theme/text-styles";
6 |
7 | export default defineConfig({
8 | preflight: true,
9 | include: ["./**/*.tsx"],
10 | presets: ["@pandacss/dev/presets"],
11 | outdir: "design-system",
12 | jsxFramework: "react",
13 | globalCss,
14 | conditions: {
15 | groupSelected: ".group:where([aria-selected=true], [data-selected]) &",
16 | },
17 | theme: {
18 | extend: {
19 | recipes,
20 | textStyles,
21 | semanticTokens: {
22 | colors: {
23 | fg: {
24 | default: { value: { base: "{colors.gray.900}", _dark: "white" } },
25 | emphasized: {
26 | value: { base: "{colors.gray.700}", _dark: "{colors.gray.200}" },
27 | },
28 | muted: {
29 | value: { base: "{colors.gray.500}", _dark: "{colors.gray.400}" },
30 | },
31 | subtle: {
32 | value: { base: "{colors.gray.400}", _dark: "{colors.gray.500}" },
33 | },
34 | placeholder: {
35 | value: { base: "{colors.gray.600}", _dark: "{colors.gray.400}" },
36 | }, // check
37 | inverted: {
38 | default: { value: { base: "white", _dark: "{colors.black}" } },
39 | },
40 | },
41 | bg: {
42 | canvas: {
43 | value: { base: "{colors.gray.25}", _dark: "{colors.black}" },
44 | },
45 | surface: {
46 | value: { base: "white", _dark: "{colors.gray.850}" },
47 | },
48 | muted: {
49 | value: { base: "{colors.gray.300}", _dark: "{colors.gray.700}" },
50 | },
51 | subtle: {
52 | value: { base: "{colors.gray.100}", _dark: "{colors.gray.800}" },
53 | },
54 | },
55 | accent: {
56 | default: {
57 | value: {
58 | base: "{colors.purple.400}",
59 | _dark: "{colors.purple.400}",
60 | },
61 | },
62 | emphasized: {
63 | value: {
64 | base: "{colors.blue.500}",
65 | _dark: "{colors.blue.500}",
66 | },
67 | },
68 | muted: {
69 | value: {
70 | base: "{colors.blue.400}",
71 | _dark: "{colors.blue.300}",
72 | },
73 | },
74 | subtle: {
75 | value: {
76 | base: "{colors.blue.50}",
77 | _dark: "{colors.blue.900}",
78 | },
79 | },
80 | },
81 | border: {
82 | default: {
83 | value: { base: "{colors.gray.50}", _dark: "{colors.gray.800}" },
84 | },
85 | emphasized: {
86 | value: { base: "{colors.gray.300}", _dark: "{colors.gray.800}" },
87 | },
88 | },
89 | },
90 | shadows: {
91 | xs: {
92 | value: {
93 | base: "0px 0px 1px rgba(48, 49, 51, 0.05), 0px 1px 2px rgba(48, 49, 51, 0.1)",
94 | _dark: "0px 0px 1px #0D0D0D, 0px 1px 2px rgba(13, 13, 13, 0.9)",
95 | },
96 | },
97 | sm: {
98 | value: {
99 | base: "0px 0px 1px rgba(48, 49, 51, 0.05), 0px 2px 4px rgba(48, 49, 51, 0.1)",
100 | _dark: "0px 0px 1px #0D0D0D, 0px 2px 4px rgba(13, 13, 13, 0.9)",
101 | },
102 | },
103 | md: {
104 | value: {
105 | base: "0px 0px 1px rgba(48, 49, 51, 0.05), 0px 4px 8px rgba(48, 49, 51, 0.1)",
106 | _dark: "0px 0px 1px #0D0D0D, 0px 4px 8px rgba(13, 13, 13, 0.9)",
107 | },
108 | },
109 | lg: {
110 | value: {
111 | base: "0px 0px 1px rgba(48, 49, 51, 0.05), 0px 8px 16px rgba(48, 49, 51, 0.1)",
112 | _dark: "0px 0px 1px #0D0D0D, 0px 8px 16px rgba(13, 13, 13, 0.9)",
113 | },
114 | },
115 | xl: {
116 | value: {
117 | base: "0px 0px 1px rgba(48, 49, 51, 0.05), 0px 16px 24px rgba(48, 49, 51, 0.1)",
118 | _dark: "0px 0px 1px #0D0D0D, 0px 16px 24px rgba(13, 13, 13, 0.9)",
119 | },
120 | },
121 | },
122 | },
123 | tokens: {
124 | lineHeights: {
125 | relaxed: { value: "1.75" },
126 | },
127 | colors: {
128 | lightGrey: { value: "#F6F9FC" },
129 | black: { value: "#1C1917" },
130 | gray: {
131 | 50: { value: "#f2f2f2" },
132 | 100: { value: "#d9d9d9" },
133 | 200: { value: "#bfbfbf" },
134 | 300: { value: "#a6a6a6" },
135 | 400: { value: "#8c8c8c" },
136 | 500: { value: "#737373" },
137 | 600: { value: "#595959" },
138 | 700: { value: "#404040" },
139 | 800: { value: "#262626" },
140 | 850: { value: "#191919" },
141 | 900: { value: "#0d0d0d" },
142 | },
143 | orange: {
144 | 50: { value: "#F6E1DB" },
145 | 100: { value: "#EEC2B7" },
146 | 200: { value: "#E49582" },
147 | 300: { value: "#DE7960" },
148 | 400: { value: "#EB5E41" },
149 | 500: { value: "#BD4E34" },
150 | 600: { value: "#953D2B" },
151 | 700: { value: "#662314" },
152 | 800: { value: "#451D14" },
153 | 900: { value: "#391915" },
154 | },
155 | brown: {
156 | 50: { value: "#78574F" },
157 | 100: { value: "#5B4039" },
158 | 200: { value: "#4E3630" },
159 | 300: { value: "#3D2925" },
160 | 400: { value: "#33221E" },
161 | 500: { value: "#2D1D19" },
162 | 600: { value: "#261916" },
163 | 700: { value: "#201412" },
164 | 800: { value: "#1D1615" },
165 | 900: { value: "#0F0705" },
166 | },
167 | },
168 | spacing: {
169 | "4.5": { value: "1.125rem" },
170 | },
171 | sizes: {
172 | "15": { value: "3.75rem" },
173 | "18": { value: "4.5rem" },
174 | },
175 | },
176 | },
177 | },
178 | });
179 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [],
3 | plugins: ["@pandacss/dev/postcss"],
4 | };
5 |
--------------------------------------------------------------------------------
/theme/global-css.ts:
--------------------------------------------------------------------------------
1 | import { defineGlobalStyles } from "@pandacss/dev";
2 |
3 | export const globalCss = defineGlobalStyles({
4 | html: {
5 | lineHeight: 1.5,
6 | textRendering: "optimizeLegibility",
7 | MozOsxFontSmoothing: "grayscale",
8 | WebkitFontSmoothing: "antialiased",
9 | WebkitTextSizeAdjust: "100%",
10 | minHeight: "100%",
11 | },
12 | body: {
13 | backgroundColor: "bg.canvas",
14 | color: "fg.default",
15 | fontFamily: "'Poppins', sans-serif",
16 | flexGrow: "1",
17 | _dark: {
18 | colorScheme: "dark",
19 | },
20 | },
21 | "html, body": {
22 | display: "flex",
23 | flexDirection: "column",
24 | height: "unset !important",
25 | },
26 | "*, *::before, *::after": {
27 | borderColor: "border.default",
28 | borderStyle: "solid",
29 | },
30 | "*::placeholder": {
31 | opacity: 1,
32 | color: "fg.placeholder",
33 | },
34 | "h1, h2, h3, h4, h5, h6": {
35 | fontFamily: "var(--font-mona-sans), sans-serif",
36 | },
37 | a: {
38 | textDecoration: "none",
39 | },
40 | hr: {
41 | borderBottomWidth: "1px",
42 | },
43 | svg: {
44 | maxW: "unset",
45 | },
46 | });
47 |
--------------------------------------------------------------------------------
/theme/recipes/button.ts:
--------------------------------------------------------------------------------
1 | import { createAnatomy } from "@ark-ui/react";
2 | import { defineParts, defineRecipe } from "@pandacss/dev";
3 |
4 | const parts = defineParts(
5 | createAnatomy("button").parts("root", "icon", "spinner").build()
6 | );
7 |
8 | export const button = defineRecipe({
9 | name: "button",
10 | description: "A button styles",
11 | base: parts({
12 | root: {
13 | alignItems: "center",
14 | appearance: "none",
15 | borderRadius: "lg",
16 | cursor: "pointer",
17 | display: "inline-flex",
18 | fontWeight: "semibold",
19 | justifyContent: "center",
20 | outline: "none",
21 | position: "relative",
22 | transitionProperty: "base",
23 | transitionDuration: "100",
24 | transitionTimingFunction: "ease-out",
25 | userSelect: "none",
26 | verticalAlign: "middle",
27 | whiteSpace: "nowrap",
28 | },
29 | icon: {
30 | display: "inline-flex",
31 | alignSelf: "center",
32 | flexShrink: "0",
33 | },
34 | }),
35 | defaultVariants: {
36 | variant: "primary",
37 | size: "md",
38 | },
39 | variants: {
40 | variant: {
41 | primary: {
42 | color: "white",
43 | backgroundColor: "blue.400",
44 | _hover: {
45 | backgroundColor: "blue.500",
46 | },
47 | _focusVisible: {
48 | zIndex: 1,
49 | "--shadow": {
50 | base: "colors.blue.50",
51 | _dark: "colors.gray.700",
52 | },
53 | boxShadow: "0 0 0 4px var(--shadow)",
54 | },
55 | },
56 | secondary: {
57 | background: "bg.surface",
58 | borderWidth: "1px",
59 | borderColor: "border.emphasized",
60 | boxShadow: "xs",
61 | color: "fg.emphasized",
62 | _hover: {
63 | color: "fg.default",
64 | background: "bg.subtle",
65 | _disabled: {
66 | borderColor: "border.default",
67 | color: "fg.subtle",
68 | cursor: "not-allowed",
69 | },
70 | },
71 | _selected: {
72 | background: "bg.subtle",
73 | },
74 | _focusVisible: {
75 | zIndex: 1,
76 | "--shadow": {
77 | base: "colors.gray.100",
78 | _dark: "colors.gray.800",
79 | },
80 | boxShadow: "0 0 0 4px var(--shadow)",
81 | },
82 | _disabled: {
83 | borderColor: "border.default",
84 | color: "fg.subtle",
85 | cursor: "not-allowed",
86 | },
87 | },
88 | tertiary: {
89 | background: "transparent",
90 | color: "fg.emphasized",
91 | _hover: {
92 | color: "fg.default",
93 | background: "bg.subtle",
94 | _disabled: {
95 | borderColor: "border.default",
96 | color: "fg.subtle",
97 | cursor: "not-allowed",
98 | },
99 | },
100 | _selected: {
101 | background: "bg.subtle",
102 | },
103 | _focusVisible: {
104 | zIndex: 1,
105 | "--shadow": {
106 | base: "colors.gray.100",
107 | _dark: "colors.gray.800",
108 | },
109 | boxShadow: "0 0 0 4px var(--shadow)",
110 | },
111 | _disabled: {
112 | borderColor: "border.default",
113 | color: "fg.subtle",
114 | cursor: "not-allowed",
115 | },
116 | },
117 | link: {
118 | background: "transparent",
119 | color: "fg.muted",
120 | _hover: {
121 | color: "fg.emphasized",
122 | },
123 | _disabled: {
124 | color: "fg.subtle",
125 | cursor: "not-allowed",
126 | },
127 | height: "auto !important",
128 | px: "0 !important",
129 | },
130 | },
131 | size: {
132 | xs: parts({
133 | root: {
134 | h: "8",
135 | minW: "8",
136 | textStyle: "xs",
137 | px: "3",
138 | },
139 | icon: {
140 | fontSize: "1.0rem",
141 | "--icon-spacing": "0.5rem",
142 | },
143 | }),
144 | sm: parts({
145 | root: {
146 | h: "9",
147 | minW: "9",
148 | textStyle: "sm",
149 | px: "3.5",
150 | },
151 | icon: {
152 | fontSize: "1.25rem",
153 | "--icon-spacing": "0.5rem",
154 | },
155 | }),
156 | md: parts({
157 | root: {
158 | h: "10",
159 | minW: "10",
160 | textStyle: "sm",
161 | px: "4",
162 | },
163 | icon: {
164 | fontSize: "1.25rem",
165 | "--icon-spacing": "0.5rem",
166 | },
167 | }),
168 | lg: parts({
169 | root: {
170 | h: "11",
171 | minW: "11",
172 | px: "4.5",
173 | textStyle: "md",
174 | },
175 | icon: {
176 | fontSize: "1.25rem",
177 | "--icon-spacing": "0.5rem",
178 | },
179 | }),
180 | xl: parts({
181 | root: {
182 | h: "12",
183 | minW: "12",
184 | px: "5",
185 | textStyle: "md",
186 | },
187 | icon: {
188 | fontSize: "1.25rem",
189 | "--icon-spacing": "0.5rem",
190 | },
191 | }),
192 | "2xl": parts({
193 | root: {
194 | h: "15",
195 | minW: "15",
196 | px: "7",
197 | fontSize: "lg",
198 | },
199 | icon: {
200 | fontSize: "1.5rem",
201 | "--icon-spacing": "0.75rem",
202 | },
203 | }),
204 | },
205 | },
206 | });
207 |
--------------------------------------------------------------------------------
/theme/recipes/dialog.ts:
--------------------------------------------------------------------------------
1 | import { dialogAnatomy } from "@ark-ui/react";
2 | import { defineParts, defineRecipe } from "@pandacss/dev";
3 |
4 | const parts = defineParts(dialogAnatomy.build());
5 |
6 | export const dialog = defineRecipe({
7 | name: "dialog",
8 | description: "A dialog style",
9 | base: parts({
10 | backdrop: {
11 | background: {
12 | base: "gray.700",
13 | _dark: "black",
14 | },
15 | opacity: "0.7",
16 | inset: "0",
17 | position: "fixed",
18 | zIndex: "200",
19 | pointerEvents: "auto",
20 | },
21 | container: {
22 | alignItems: "center",
23 | display: "flex",
24 | inset: "0",
25 | justifyContent: "center",
26 | position: "fixed",
27 | zIndex: "200",
28 | },
29 | content: {
30 | background: "bg.surface",
31 | borderRadius: "xl",
32 | boxShadow: "lg",
33 | minW: "sm",
34 | position: "relative",
35 | },
36 | title: {
37 | fontWeight: "semibold",
38 | textStyle: "lg",
39 | },
40 | description: {
41 | color: "fg.muted",
42 | textStyle: "sm",
43 | },
44 | }),
45 | });
46 |
--------------------------------------------------------------------------------
/theme/recipes/index.ts:
--------------------------------------------------------------------------------
1 | import { button } from "./button";
2 | import { dialog } from "./dialog";
3 | import { input } from "./input";
4 | import { select } from "./select";
5 | import { splitter } from "./splitter";
6 |
7 | export const recipes = {
8 | button,
9 | dialog,
10 | input,
11 | select,
12 | splitter,
13 | };
14 |
--------------------------------------------------------------------------------
/theme/recipes/input.ts:
--------------------------------------------------------------------------------
1 | import { defineRecipe } from "@pandacss/dev";
2 |
3 | export const input = defineRecipe({
4 | name: "input",
5 | description: "An input style",
6 | base: {
7 | width: "100%",
8 | minWidth: 0,
9 | outline: 0,
10 | position: "relative",
11 | appearance: "none",
12 | transitionProperty: "base",
13 | transitionDuration: "100",
14 | _disabled: {
15 | opacity: 0.4,
16 | cursor: "not-allowed",
17 | },
18 | },
19 | defaultVariants: {
20 | variant: "outline",
21 | size: "md",
22 | },
23 | variants: {
24 | variant: {
25 | outline: {
26 | background: "bg.surface",
27 | borderRadius: "lg",
28 | borderWidth: "1px",
29 | color: "fg.default",
30 | textAlign: "left",
31 | borderColor: "border.default",
32 | _focus: {
33 | zIndex: 1,
34 | "--shadow": {
35 | base: "colors.purple.500",
36 | _dark: "colors.purple.200",
37 | },
38 | boxShadow: "0 0 0 1px var(--shadow)",
39 | borderColor: "accent.default",
40 | },
41 | },
42 | },
43 | size: {
44 | sm: { px: "2.5", h: "9", minW: "9", textStyle: "sm" },
45 | md: { px: "3", h: "10", minW: "10", textStyle: "md" },
46 | lg: { px: "3.5", h: "11", minW: "11", textStyle: "md" },
47 | xl: { px: "4", h: "12", minW: "12", textStyle: "md" },
48 | "2xl": { px: "2", h: "16", minW: "16", textStyle: "3xl" },
49 | },
50 | },
51 | });
52 |
--------------------------------------------------------------------------------
/theme/recipes/select.ts:
--------------------------------------------------------------------------------
1 | import { selectAnatomy } from "@ark-ui/react";
2 | import { defineParts, defineRecipe } from "@pandacss/dev";
3 |
4 | const parts = defineParts(selectAnatomy.build());
5 |
6 | export const select = defineRecipe({
7 | name: "select",
8 | description: "A select style",
9 | base: parts({
10 | content: {
11 | background: "bg.surface",
12 | borderRadius: "lg",
13 | borderWidth: "1px",
14 | boxShadow: "lg",
15 | listStyle: "none",
16 | maxW: "calc(100vw - 1rem)",
17 | p: "1",
18 | },
19 | trigger: {
20 | alignItems: "center",
21 | cursor: "pointer",
22 | display: "flex",
23 | justifyContent: "space-between",
24 | outline: 0,
25 | position: "relative",
26 | appearance: "none",
27 | transitionProperty: "base",
28 | transitionDuration: "100",
29 | width: "full",
30 | whiteSpace: "nowrap",
31 | _disabled: {
32 | opacity: 0.4,
33 | cursor: "not-allowed",
34 | },
35 | },
36 | option: {
37 | borderRadius: "md",
38 | cursor: "pointer",
39 | mb: "1",
40 | _hover: {
41 | background: "bg.subtle",
42 | },
43 | _selected: {
44 | background: "bg.subtle",
45 | },
46 | _focus: {
47 | background: "bg.subtle",
48 | },
49 | _last: {
50 | mb: "0",
51 | },
52 | },
53 | positioner: {
54 | zIndex: "1",
55 | },
56 | }),
57 | defaultVariants: {
58 | variant: "outline",
59 | size: "md",
60 | },
61 | variants: {
62 | variant: {
63 | outline: parts({
64 | trigger: {
65 | background: "bg.surface",
66 | borderRadius: "lg",
67 | borderWidth: "1px",
68 | color: "fg.default",
69 | textAlign: "left",
70 | width: "full",
71 | borderColor: "border.default",
72 | _focus: {
73 | zIndex: 1,
74 | "--shadow": {
75 | base: "colors.purple.500",
76 | _dark: "colors.purple.200",
77 | },
78 | boxShadow: "0 0 0 1px var(--shadow)",
79 | borderColor: "accent.default",
80 | },
81 | },
82 | }),
83 | },
84 | size: {
85 | xs: parts({
86 | trigger: { px: "2", h: "8", maxW: "2xs", textStyle: "sm" },
87 | content: { w: "2xs" },
88 | option: { textStyle: "sm", p: "1" },
89 | }),
90 | sm: parts({
91 | trigger: { px: "2.5", h: "9", maxW: "2xs", textStyle: "sm" },
92 | content: { w: "2xs" },
93 | option: { textStyle: "sm", p: "1.5" },
94 | }),
95 | md: parts({
96 | trigger: { px: "3", h: "10", maxW: "xs", textStyle: "md" },
97 | content: { w: "xs" },
98 | option: { textStyle: "md", p: "2" },
99 | }),
100 | lg: parts({
101 | trigger: { px: "3.5", h: "11", maxW: "xs", textStyle: "md" },
102 | content: { w: "xs" },
103 | option: { textStyle: "md" },
104 | }),
105 | xl: parts({
106 | trigger: { px: "4", h: "12", maxW: "xs", textStyle: "md" },
107 | content: { w: "xs" },
108 | option: { textStyle: "md" },
109 | }),
110 | "2xl": parts({
111 | trigger: { px: "2", h: "16", maxW: "xs", textStyle: "3xl" },
112 | content: { w: "xs" },
113 | option: { textStyle: "3xl" },
114 | }),
115 | },
116 | },
117 | });
118 |
--------------------------------------------------------------------------------
/theme/recipes/splitter.ts:
--------------------------------------------------------------------------------
1 | import { splitterAnatomy } from "@ark-ui/react";
2 | import { defineParts, defineRecipe } from "@pandacss/dev";
3 |
4 | const parts = defineParts(splitterAnatomy.build());
5 |
6 | const partDetails = splitterAnatomy.build();
7 | export const splitter = defineRecipe({
8 | name: "splitter",
9 | description: "A splitter style",
10 | base: parts({
11 | root: {
12 | width: "full",
13 | gap: "2",
14 | '&[data-orientation="horizontal"]': {
15 | height: "300px",
16 | },
17 | '&[data-orientation="vertical"]': {
18 | width: "800px",
19 | height: "600px",
20 | flexDirection: "column",
21 | },
22 | [`& ${partDetails.panel.selector}:has(${partDetails.panel.selector})` as any]:
23 | {
24 | border: "none",
25 | },
26 | },
27 | panel: {
28 | display: "flex",
29 | border: "1px solid lightgray",
30 | overflow: "auto",
31 | },
32 | resizeTrigger: {
33 | background: "#ebebeb",
34 | borderRadius: "8px",
35 | display: "flex",
36 | alignItems: "center",
37 | justifyContent: "center",
38 | transition: "background-color 0.2s ease-in-out",
39 | outline: "0",
40 | position: "relative",
41 | '&[data-orientation="horizontal"]': {
42 | margin: "min(1rem, 20%) 0",
43 | minHeight: "50px",
44 | },
45 | '&[data-orientation="vertical"]': {
46 | minHeight: "1",
47 | margin: "0 min(1rem, 20%)",
48 | },
49 |
50 | _before: {
51 | content: '""',
52 | position: "absolute",
53 | background: "#7d7d7d1a",
54 | top: 0,
55 | left: 0,
56 | zIndex: 1,
57 | display: "block",
58 | opacity: 0,
59 | transition: "opacity .4s",
60 | },
61 | '&[data-orientation="horizontal"]:hover:before': {
62 | opacity: 1,
63 | },
64 | '&[data-orientation="horizontal"]:before': {
65 | right: "-10px",
66 | height: "full",
67 | width: "2",
68 | },
69 | _hover: {
70 | background: "#7d7d7d1a",
71 | color: "white",
72 | },
73 | _active: {
74 | background: "#3f51b5",
75 | color: "white",
76 | },
77 | _disabled: {
78 | opacity: 0.5,
79 | },
80 | },
81 | }),
82 | });
83 |
--------------------------------------------------------------------------------
/theme/text-styles.ts:
--------------------------------------------------------------------------------
1 | import { defineTextStyles } from "@pandacss/dev";
2 |
3 | export const textStyles = defineTextStyles({
4 | xs: { value: { fontSize: "xs", lineHeight: "1.125rem" } },
5 | sm: { value: { fontSize: "sm", lineHeight: "1.25rem" } },
6 | md: { value: { fontSize: "md", lineHeight: "1.5rem" } },
7 | lg: { value: { fontSize: "lg", lineHeight: "1.75rem" } },
8 | xl: { value: { fontSize: "xl", lineHeight: "1.875rem" } },
9 | "2xl": { value: { fontSize: "2xl", lineHeight: "2rem" } },
10 | "3xl": { value: { fontSize: "3xl", lineHeight: "2.375rem" } },
11 | "4xl": {
12 | value: { fontSize: "4xl", lineHeight: "2.75rem", letterSpacing: "-0.02em" },
13 | },
14 | "5xl": {
15 | value: { fontSize: "5xl", lineHeight: "3.75rem", letterSpacing: "-0.02em" },
16 | },
17 | "6xl": {
18 | value: { fontSize: "6xl", lineHeight: "4.5rem", letterSpacing: "-0.02em" },
19 | },
20 | "7xl": {
21 | value: { fontSize: "7xl", lineHeight: "5.75rem", letterSpacing: "-0.02em" },
22 | },
23 | });
24 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2019",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "baseUrl": ".",
6 | "paths": {
7 | "@/panda/css": ["./design-system/css"],
8 | "@/panda/jsx": ["./design-system/jsx"]
9 | },
10 | "allowJs": true,
11 | "skipLibCheck": true,
12 | "strict": false,
13 | "forceConsistentCasingInFileNames": true,
14 | "noEmit": true,
15 | "incremental": true,
16 | "esModuleInterop": true,
17 | "module": "esnext",
18 | "moduleResolution": "node",
19 | "resolveJsonModule": true,
20 | "isolatedModules": true,
21 | "jsx": "preserve",
22 | "plugins": [
23 | {
24 | "name": "next"
25 | }
26 | ]
27 | },
28 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
29 | "exclude": ["node_modules"]
30 | }
31 |
--------------------------------------------------------------------------------
/utils/component-config/constants.ts:
--------------------------------------------------------------------------------
1 | export enum Framework {
2 | REACT = "REACT",
3 | SOLID = "SOLID",
4 | VUE = "VUE",
5 | }
6 |
7 | export enum StyleSolution {
8 | VANILLA_CSS = "VANILLA_CSS",
9 | // PANDA_CSS = "PANDA_CSS",
10 | TAILWIND = "TAILWIND",
11 | }
12 |
13 | export enum StyleType {
14 | INLINE = "INLINE",
15 | ABSTRACTED = "ABSTRACTED",
16 | SCOPED = "SCOPED",
17 | RECIPE = "RECIPE",
18 | }
19 |
20 | export const FRAMEWORKS = {
21 | [Framework.REACT]: { label: "React", value: Framework.REACT },
22 | [Framework.SOLID]: { label: "Solid JS", value: Framework.SOLID },
23 | [Framework.VUE]: { label: "Vue", value: Framework.VUE },
24 | };
25 |
26 | export const STYLE_SOLUTIONS = {
27 | [StyleSolution.VANILLA_CSS]: {
28 | label: "Vanilla CSS",
29 | value: StyleSolution.VANILLA_CSS,
30 | types: [
31 | {
32 | label: "Scoped Styles",
33 | value: StyleType.SCOPED,
34 | },
35 | ],
36 | },
37 | // [StyleSolution.PANDA_CSS]: {
38 | // label: "Panda CSS",
39 | // value: StyleSolution.PANDA_CSS,
40 | // types: [
41 | // {
42 | // label: "Inline Styles",
43 | // value: StyleType.INLINE,
44 | // },
45 | // {
46 | // label: "Abstracted Styles",
47 | // value: StyleType.ABSTRACTED,
48 | // },
49 | // {
50 | // label: "Recipes",
51 | // value: StyleType.RECIPE,
52 | // },
53 | // ],
54 | // },
55 | [StyleSolution.TAILWIND]: {
56 | label: "Tailwind",
57 | value: StyleSolution.TAILWIND,
58 | types: [
59 | {
60 | label: "Inline Style",
61 | value: StyleType.INLINE,
62 | },
63 | ],
64 | },
65 | };
66 |
67 | export const defaultConfig = {
68 | framework: Framework.REACT,
69 | styleSolution: StyleSolution.VANILLA_CSS,
70 | styleType: StyleType.SCOPED,
71 | };
72 |
--------------------------------------------------------------------------------
/utils/component-config/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | STYLE_SOLUTIONS,
3 | StyleSolution,
4 | } from "utils/component-config/constants";
5 | import { ComponentConfig, ConfigSetterArg, ConfigValue } from "utils/types";
6 |
7 | export const setComponentConfig = (
8 | key: K,
9 | value: ConfigValue,
10 | setConfig: (newConfigOrConfigFn: ConfigSetterArg) => void
11 | ) => {
12 | if (key === "styleSolution") {
13 | setConfig((config) => ({
14 | ...config,
15 | [key]: value,
16 | styleType: Object.values(STYLE_SOLUTIONS[value as StyleSolution].types)[0]
17 | .value,
18 | }));
19 | return;
20 | }
21 |
22 | setConfig((config) => ({
23 | ...config,
24 | [key]: value,
25 | }));
26 | };
27 |
--------------------------------------------------------------------------------
/utils/component-setup/constants.ts:
--------------------------------------------------------------------------------
1 | import { Framework, StyleSolution } from "utils/component-config/constants";
2 |
3 | export const components = [
4 | { id: "accordion", label: "Accordion" },
5 | { id: "checkbox", label: "Checkbox" },
6 | { id: "dialog", label: "Dialog" },
7 | { id: "hover-card", label: "Hover Card" },
8 | { id: "menu", label: "Menu" },
9 | { id: "number-input", label: "Number Input" },
10 | { id: "pagination", label: "Pagination" },
11 | { id: "pin-input", label: "Pin Input" },
12 | { id: "popover", label: "Popover" },
13 | { id: "radio-group", label: "Radio Group" },
14 | { id: "range-slider", label: "Range Slider" },
15 | { id: "rating-group", label: "Rating Group" },
16 | { id: "select", label: "Select" },
17 | { id: "slider", label: "Slider" },
18 | { id: "splitter", label: "Splitter" },
19 | { id: "tabs", label: "Tabs" },
20 | { id: "tags-input", label: "Tags Input" },
21 | { id: "toast", label: "Toast" },
22 | { id: "tooltip", label: "Tooltip" },
23 | ] as const;
24 |
25 | export const templates = {
26 | [Framework.REACT]: "react",
27 | [Framework.SOLID]: "solid",
28 | [Framework.VUE]: undefined,
29 | } as const;
30 |
31 | export const getArkPackage = (
32 | framework: Framework,
33 | styleSolution: StyleSolution
34 | ) => {
35 | if (framework === Framework.REACT) {
36 | const packages = {
37 | "@ark-ui/react": "latest",
38 | "react-icons": "latest",
39 | "react-helmet": "latest",
40 | };
41 | switch (styleSolution) {
42 | case StyleSolution.VANILLA_CSS:
43 | return packages;
44 |
45 | case StyleSolution.TAILWIND:
46 | return { ...packages };
47 |
48 | default:
49 | break;
50 | }
51 | } else return;
52 | };
53 |
--------------------------------------------------------------------------------
/utils/component-setup/index.ts:
--------------------------------------------------------------------------------
1 | import prettier from "prettier";
2 | import parserBabel from "prettier/parser-babel";
3 | import parserHtml from "prettier/parser-html";
4 | import parserPostCSS from "prettier/parser-postcss";
5 |
6 | import {
7 | Framework,
8 | StyleSolution,
9 | StyleType,
10 | } from "utils/component-config/constants";
11 | import { components } from "utils/component-setup/constants";
12 | import { ComponentId } from "utils/types";
13 |
14 | export const getComponent = (id: ComponentId) =>
15 | components.find((component) => component.id === id);
16 |
17 | export type ComponentSetup = {
18 | visibleFiles: string[];
19 | files: Record;
20 | };
21 |
22 | export const getComponentSetup = (
23 | framework: Framework,
24 | styleSolution: StyleSolution,
25 | styleType: StyleType,
26 | componentId: ComponentId
27 | ): ComponentSetup | undefined => {
28 | try {
29 | const details =
30 | require(`component-data/${framework.toLocaleLowerCase()}/${styleSolution.toLocaleLowerCase()}/${styleType.toLocaleLowerCase()}/${componentId}`).default;
31 | return details;
32 | } catch (error) {
33 | const details =
34 | require(`component-data/${framework.toLocaleLowerCase()}/shared/404`).default;
35 | return details;
36 | }
37 | };
38 |
39 | export const formatFiles = (files: Record) => {
40 | return Object.entries(files).reduce(
41 | (acc, [fileName, code]) => ({
42 | ...acc,
43 | [fileName]: formatCode(code, fileName),
44 | }),
45 | {}
46 | );
47 | };
48 |
49 | export const formatCode = (code: string, fileName: string) => {
50 | const parser = getParser(fileName);
51 | if (!parser) return code;
52 | try {
53 | return prettier.format(code, {
54 | parser,
55 | plugins: [parserHtml, parserBabel, parserPostCSS],
56 | semi: true,
57 | singleQuote: false,
58 | });
59 | } catch (e) {
60 | console.log("e", e);
61 | return code;
62 | }
63 | };
64 |
65 | const getParser = (fileName: string) => {
66 | const ext = fileName.split(".").at(-1);
67 | if (ext === "css") return "css";
68 | if (ext === "vue") return "vue";
69 | if (["js", "jsx", "tsx"].includes(ext)) return "babel";
70 | };
71 |
--------------------------------------------------------------------------------
/utils/types.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Framework,
3 | StyleSolution,
4 | StyleType,
5 | defaultConfig,
6 | } from "utils/component-config/constants";
7 | import { getComponent } from "utils/component-setup";
8 | import { components } from "utils/component-setup/constants";
9 |
10 | export type ComponentId = (typeof components)[number]["id"];
11 |
12 | export type ComponentParams = {
13 | component: ComponentId;
14 | };
15 |
16 | export type Component = ReturnType;
17 |
18 | export type ComponentConfig = typeof defaultConfig;
19 |
20 | export type ConfigValue = V extends "framework"
21 | ? Framework
22 | : V extends "styleSolution"
23 | ? StyleSolution
24 | : V extends "styleType"
25 | ? StyleType
26 | : string;
27 |
28 | export type ConfigSetterArg =
29 | | ComponentConfig
30 | | ((config: ComponentConfig) => ComponentConfig);
31 |
--------------------------------------------------------------------------------
/utils/useColorMode.ts:
--------------------------------------------------------------------------------
1 | import { useEffectOnce, useLocalStorage, useUpdateEffect } from "usehooks-ts";
2 |
3 | export type ColorMode = "light" | "dark";
4 |
5 | export const colorModeLocalStorageKey = "arkxamples-color-mode";
6 |
7 | export const useColorMode = () => {
8 | const [colorMode, setColorMode] = useLocalStorage(
9 | colorModeLocalStorageKey,
10 | "light"
11 | );
12 |
13 | const syncColorMode = () =>
14 | colorMode === "dark"
15 | ? document.documentElement.classList.add("dark")
16 | : document.documentElement.classList.remove("dark");
17 |
18 | useEffectOnce(syncColorMode);
19 | useUpdateEffect(syncColorMode, [colorMode]);
20 |
21 | return {
22 | colorMode,
23 | toggle: () => setColorMode((prev) => (prev === "dark" ? "light" : "dark")),
24 | };
25 | };
26 |
--------------------------------------------------------------------------------
/utils/useComponentConfig.ts:
--------------------------------------------------------------------------------
1 | import {
2 | ReadonlyURLSearchParams,
3 | usePathname,
4 | useRouter,
5 | useSearchParams,
6 | } from "next/navigation";
7 | // import { useRouter } from "next/";
8 | import { useEffect } from "react";
9 | import { useLocalStorage } from "usehooks-ts";
10 |
11 | import { setComponentConfig } from "utils/component-config";
12 | import {
13 | FRAMEWORKS,
14 | STYLE_SOLUTIONS,
15 | defaultConfig,
16 | } from "utils/component-config/constants";
17 | import { ComponentConfig, ConfigSetterArg, ConfigValue } from "utils/types";
18 |
19 | export const configLocalStorageKey = "arkxamples-component-config";
20 |
21 | const validateParams = (
22 | params: ReadonlyURLSearchParams,
23 | key: string,
24 | value: string,
25 | acc: ComponentConfig
26 | ) => {
27 | switch (key) {
28 | case "framework":
29 | if (
30 | Object.keys(FRAMEWORKS).some(
31 | (f) => f.toLocaleLowerCase() === params.get(key)?.toLocaleLowerCase()
32 | )
33 | ) {
34 | return params.get(key);
35 | }
36 | return value;
37 |
38 | case "styleSolution":
39 | if (
40 | Object.keys(STYLE_SOLUTIONS).some(
41 | (ss) =>
42 | ss.toLocaleLowerCase() === params.get(key)?.toLocaleLowerCase()
43 | )
44 | ) {
45 | return params.get(key);
46 | }
47 | return value;
48 |
49 | case "styleType":
50 | //* We still need to ensure the styleType exists under the chosen styleSolution
51 | if (
52 | STYLE_SOLUTIONS[acc.styleSolution].types
53 | .map((t) => t.value)
54 | .some(
55 | (st) =>
56 | st.toLocaleLowerCase() === params.get(key)?.toLocaleLowerCase()
57 | )
58 | ) {
59 | return params.get(key);
60 | }
61 | return value;
62 |
63 | default:
64 | return value;
65 | }
66 | };
67 |
68 | export const useComponentConfig = () => {
69 | const searchParams = useSearchParams();
70 |
71 | const pathname = usePathname();
72 | const router = useRouter();
73 |
74 | const configWithParams = Object.entries(defaultConfig)
75 | //* Just so styleSolution comes before styleType, as it has to be validated first
76 | .sort(function (a, b) {
77 | if (a[0] < b[0]) {
78 | return -1;
79 | }
80 | if (a[0] > b[0]) {
81 | return 1;
82 | }
83 | return 0;
84 | })
85 | .reduce(
86 | (acc, [key, value]) => ({
87 | ...acc,
88 | [key]: validateParams(searchParams, key, value, acc),
89 | }),
90 | {} as ComponentConfig
91 | );
92 |
93 | const [config, setConfig] = useLocalStorage(
94 | configLocalStorageKey,
95 | configWithParams
96 | );
97 |
98 | const queryString = searchParams.toString();
99 |
100 | useEffect(() => {
101 | if (queryString) {
102 | setConfig(configWithParams);
103 | }
104 | router.replace(pathname);
105 | // eslint-disable-next-line react-hooks/exhaustive-deps
106 | }, [queryString]);
107 |
108 | if (typeof window === "undefined") return;
109 |
110 | const configSetter = (newConfigOrConfigFn: ConfigSetterArg) => {
111 | setConfig(
112 | typeof newConfigOrConfigFn === "function"
113 | ? newConfigOrConfigFn(config)
114 | : newConfigOrConfigFn
115 | );
116 | // router.replace(pathname);
117 | };
118 |
119 | return {
120 | ...config,
121 | setComponentConfig: (
122 | key: K,
123 | value: ConfigValue
124 | ) => setComponentConfig(key, value, configSetter),
125 | };
126 | };
127 |
128 | export const useQueryString = (tempConfig: ComponentConfig) => {
129 | const compConfig = useComponentConfig();
130 | const searchParams = new URLSearchParams();
131 |
132 | Object.entries(tempConfig).forEach(([key, value]) => {
133 | if (compConfig[key].toLocaleLowerCase() !== value.toLocaleLowerCase()) {
134 | searchParams.append(key, value);
135 | }
136 | });
137 |
138 | const paramsString = searchParams.toString();
139 |
140 | return !!paramsString ? `?${paramsString}` : "";
141 | };
142 |
--------------------------------------------------------------------------------
/utils/useComponentSetup.ts:
--------------------------------------------------------------------------------
1 | import { getComponent, getComponentSetup } from "utils/component-setup";
2 | import { ComponentId } from "utils/types";
3 |
4 | import { useComponentConfig } from "./useComponentConfig";
5 |
6 | export const useComponentSetup = (componentId: ComponentId) => {
7 | const config = useComponentConfig();
8 | if (!config) return;
9 | const { framework, styleSolution, styleType } = config;
10 |
11 | const component = getComponent(componentId as any);
12 | if (!component) {
13 | // Non existent component. Might want to handle this differently
14 | }
15 |
16 | const componentDetails = getComponentSetup(
17 | framework,
18 | styleSolution,
19 | styleType,
20 | componentId
21 | );
22 |
23 | return componentDetails;
24 | };
25 |
--------------------------------------------------------------------------------
/utils/useComponentsSearch.ts:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 |
3 | import { components } from "utils/component-setup/constants";
4 |
5 | export const useComponentsSearch = () => {
6 | const [query, setQuery] = useState("");
7 |
8 | const filteredComponents = components.filter((comp) =>
9 | comp.label.toLocaleLowerCase().includes(query.toLocaleLowerCase())
10 | );
11 |
12 | const emptyResult = !!query && filteredComponents.length < 1;
13 |
14 | return { query, setQuery, filteredComponents, emptyResult };
15 | };
16 |
--------------------------------------------------------------------------------
/utils/useSyncSandboxColorMode.ts:
--------------------------------------------------------------------------------
1 | import { useSandpack } from "@codesandbox/sandpack-react";
2 | import { useEffect } from "react";
3 |
4 | import { useColorMode } from "utils/useColorMode";
5 |
6 | export const useSyncSandboxColorMode = () => {
7 | const { colorMode } = useColorMode();
8 | const { sandpack } = useSandpack();
9 |
10 | useEffect(() => {
11 | const sender = () => {
12 | Object.values(sandpack.clients).forEach((client) => {
13 | client.iframe.contentWindow.postMessage({ colorMode }, "*");
14 | });
15 | };
16 |
17 | sender();
18 |
19 | const listener = window.addEventListener("message", function (event) {
20 | if (event.data.action === "getColorMode") {
21 | sender();
22 | }
23 | });
24 |
25 | return () => {
26 | window.removeEventListener("message", listener as any);
27 | };
28 | }, [colorMode, sandpack.clients]);
29 | };
30 |
--------------------------------------------------------------------------------