diff --git a/.storybook/main.ts b/.storybook/main.ts index 4d3d1b925..7d72cd85d 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -58,8 +58,33 @@ const storybookConfig: StorybookConfig = { }) ].filter(Boolean); + // Modify the css-loader options to simplify the class names + // By default, with the config, the classnames are like this: GETEs8cGi4WwwvV1ooFy MUs8LC8twKwy5uAnhOWJ PafTkO4uwI6M3m4HX7JI + // With this new config, the classnames are like this: hop-Button___GETEs hop-Button--primary___MUs8L hop-Button--md___PafTk + for (const rule of config.module?.rules || []) { + if (typeof rule === "object" && rule?.use && Array.isArray(rule.use)) { + for (const loader of rule.use) { + if (typeof loader === "object" && loader?.loader?.includes("css-loader")) { + const cssLoader = loader; + if (cssLoader && typeof cssLoader === "object") { + const previousOptions = typeof cssLoader.options === "string" ? { } : cssLoader.options; + cssLoader.options = { + ...previousOptions, + modules: { + ...((typeof previousOptions?.modules === "string" ? { mode: previousOptions?.modules } : previousOptions?.modules)), + auto: true, + localIdentName: "[local]___[hash:base64:5]" + } + }; + } + } + } + } + } + return config; } }; + export default storybookConfig; diff --git a/apps/docs/.eslintrc.json b/apps/docs/.eslintrc.json index c632ceb3b..82295d8eb 100644 --- a/apps/docs/.eslintrc.json +++ b/apps/docs/.eslintrc.json @@ -22,7 +22,9 @@ "Switcher": true, "IconSpecTable": true, "PreviewComponent": true, - "MigrateGuide": true + "MigrateGuide": true, + "PackageInstallation": true, + "PropTable": true }, "overrides": [ { diff --git a/apps/docs/app/globals.css b/apps/docs/app/globals.css index 00ecf5523..93f4f8360 100644 --- a/apps/docs/app/globals.css +++ b/apps/docs/app/globals.css @@ -58,14 +58,6 @@ a { display: flex; } -.hd-home { - display: flex; - flex-direction: column; - gap: 3rem; - min-height: 40vh; - justify-content: center; -} - .hd-display { font-size: var(--hd-step-5); font-weight: 500; diff --git a/apps/docs/app/home.css b/apps/docs/app/home.css new file mode 100644 index 000000000..ceca49135 --- /dev/null +++ b/apps/docs/app/home.css @@ -0,0 +1,594 @@ +.hd-home__heading { + align-items: center; + display: flex; + flex-direction: column; + text-align: center; + margin: 0 auto; + max-width: 43rem; +} + +.hd-home__header { + font-size: 2.25rem; + line-height: 1.3333; +} + +.hd-home__tagline { + color: var(--hd-color-neutral-text-weak); + font-size: 1rem; + line-height: 1.5; + margin-top: var(--hd-space-1); + max-width: 60ch; +} + +.hd-home__ctas { + display: flex; + gap: var(--hd-space-3); + justify-content: center; + margin-top: var(--hd-space-4); +} + +.hd-home__features { + display: grid; + gap: var(--hd-space-4); + grid-template-columns: repeat(1, 1fr); + margin-top: var(--hd-space-10); + text-align: center; +} + +.hd-home__feature-item { + display: flex; + flex-direction: column; + align-items: center; +} + +.hd-home__feature-title { + justify-content: center; + display: flex; + font-size: 1.125rem; + gap: var(--hd-space-1); + line-height: 1.3333; +} + +.hd-home-feature-title__icon path { + height: var(--hd-space-3); + aspect-ratio: 1/1; + stroke: var(--hd-color-neutral-icon); +} + +@media screen and (width >= 37.5rem) { + .hd-home__features { + grid-template-columns: repeat(2, 1fr); + text-align: left; + } + + .hd-home__feature-item { + align-items: start; + } +} + +@media screen and (width >= 48rem) { + .hd-home__features { + grid-template-columns: repeat(4, 1fr); + } +} + +.hd-icon-fill { + fill: var(--hd-color-neutral-icon); + stroke: transparent; +} + +.hd-icon-fill path { + stroke: transparent; +} + +.hd-home__feature-copy { + color: var(--hd-color-neutral-text-weak); + font-size: 0.875rem; + line-height: 1.4285; + margin-top: var(--hd-space-1); + max-width: 50ch; +} + +/* Samples Section */ +.hd-home-samples { + display: grid; + gap: var(--hd-space-3); + grid-template-columns: 1fr; + margin-top: var(--hd-space-10); +} + +@media screen and (width >= 78.75rem) { + .hd-home-samples { + grid-template-columns: repeat(2, 1fr); + } +} + +.hd-home-sample__item { + --background: var(--hd-white); + --color: var(--hd-neutral-50); + + background: linear-gradient(90deg, var(--background) 0.625rem, transparent 1%) 50%, linear-gradient(var(--background) 0.625rem, transparent 1%) 50%, var(--color); + background-size: 0.75rem 0.75rem; + border: var(--hd-border-size) solid var(--hd-color-neutral-border); + border-radius: var(--hd-space-2); + padding: var(--hd-space-3); + position: relative; +} + +[data-theme="dark"] .hd-home-sample__item { + --background: var(--hd-neutral-900); + --color: var(--hd-neutral-800); +} + +a.hd-home-sample__item:hover { + box-shadow: 0 0.625rem 0.625rem calc(-1 * 0.0313rem) rgba(0 0 0 / 6%), 0 0.1875rem 0.1875rem calc(-1 * 0.0938rem) rgba(0 0 0 / 6%), 0 0.375rem 0.375rem calc(-1 * 0.0938rem) rgba(0 0 0 / 6%), 0 0.75rem 0.75rem calc(-1 * 0.375rem) rgba(0 0 0 / 6%), 0 1.5rem 1.5rem calc(-1 * 0.75rem) rgba(0 0 0 / 6%); + transform: translate(-0.125rem, -0.125rem); + transition: box-shadow 0.3s ease, transform 0.2s ease-in; +} + +a.hd-home-sample__item:hover .hd-home-sample__title-icon { + opacity: 1; + transform: translateX(0); +} + +a.hd-home-sample__item:hover::after { + bottom: -0.25rem; + content: ""; + display: block; + height: 0.25rem; + left: 0; + position: absolute; + width: 100%; +} + +.hd-home-sample__title { + align-items: center; + align-self: flex-start; + color: var(--hd-color-neutral-text); + display: flex; + font-size: 1.25rem; + gap: 0.25rem; + line-height: 1.2; +} + +.hd-home-sample__title-wrap { + align-items: center; + display: flex; + gap: 0.5rem; +} + +.hd-home-sample__title-icon { + fill: var(--hd-color-neutral-icon); + opacity: 0; + transform: translateX(-1rem); + transition: opacity 0.2s ease, transform 0.1s ease-in; +} + +.hd-home-sample__tagline { + color: var(--hd-color-neutral-text-weak); + font-size: 1rem; + line-height: 1.5; + margin-top: var(--hd-space-05); + margin-bottom: var(--hd-space-3); +} + +.hd-home-samples__row { + display: grid; + grid-template-columns: 1fr; + gap: 1.5rem; +} + +@media screen and (width >= 37.5rem) { + .hd-home-samples__row { + grid-template-columns: repeat(2, 1fr); + } +} + +.hd-home-samples__col { + display: grid; + gap: 1.5rem; +} + +.hd-home-samples__main-wrapper { + grid-template-columns: 1fr; +} + +@media screen and (width >= 62rem) { + .hd-home-samples__main-wrapper { + grid-template-columns: repeat(2, 1fr); + } +} + +@media screen and (width >= 78.75rem) { + .hd-home-samples__main-wrapper { + grid-template-columns: 1fr; + } +} + +/* colors sample */ +.hd-home-sample__colors { + align-self: start; + display: grid; + justify-content: flex-end; + gap: var(--hd-space-1); + margin-block: calc(-1 * var(--hd-space-1)); +} + +.hd-home-sample__colors-row { + display: flex; + gap: var(--hd-space-1); +} + +.hd-home-sample__color { + border-radius: var(--hd-space-1); + display: flex; + height: 1.875rem; + width: 1.875rem; +} + +.hd-home-sample__item-colors { + display: flex; + gap: var(--hd-space-1); + justify-content: space-between; +} + +/* Rock Color */ +.hd-home-sample__color-rock-200 { + background-color: #B3B3B1; +} + +.hd-home-sample__color-rock-300 { + background-color: #959593; +} + +.hd-home-sample__color-rock-400 { + background-color: #777775; +} + +.hd-home-sample__color-rock-500 { + background-color: #6C6C6B; +} + +/* Sapphire Color */ +.hd-home-sample__color-sapphire-200 { + background-color: #95B1FF; +} + +.hd-home-sample__color-sapphire-300 { + background-color: #6C8FFD; +} + +.hd-home-sample__color-sapphire-400 { + background-color: #4767FE; +} + +.hd-home-sample__color-sapphire-500 { + background-color: #3B57FF; +} + +/* Sizes */ +.hd-home-sample__sizes { + display: flex; + gap: var(--hd-space-1); + margin-block: calc(-1 * var(--hd-space-1)); +} + +.hd-home-sample__item-sizes { + display: flex; + justify-content: space-between; + gap: var(--hd-space-1); + flex-wrap: wrap; +} + +.hd-home-sample__size { + display: flex; + flex-direction: column; + gap: var(--hd-space-05); +} + +.hd-home-sample__size-text { + color: var(--hd-color-accent-text); + font-size: 0.625rem; + text-align: right; +} + +.hd-home-sample__size-bar { + background-color: var(--hd-color-accent-surface); + min-height: 3.5rem; + height: 100%; +} + +.hd-home-sample__size-16 .hd-home-sample__size-bar { + width: 1rem; +} + +.hd-home-sample__size-24 .hd-home-sample__size-bar { + width: 1.5rem; +} + +.hd-home-sample__size-32 .hd-home-sample__size-bar { + width: 2rem; +} + +.hd-home-sample__size-40 .hd-home-sample__size-bar { + width: 2.5rem; +} + +/* Icons */ +.hd-home-sample__icons { + display: flex; + gap: var(--hd-space-2); + flex-direction: column; + flex-grow: 1; + justify-content: space-between +} + +.hd-home-sample__item-icons { + display: flex; + flex-direction: column; +} + +.hd-home-sample__icons-row.hd-home-sample__icons-extra-row { + display: none; +} + +@media screen and (width >= 62rem) { + .hd-home-sample__icons { + gap: var(--hd-space-3); + } + + .hd-home-sample__icons-row.hd-home-sample__icons-extra-row { + display: flex; + } +} + +@media screen and (width >= 78.75rem) { + .hd-home-sample__icons { + gap: var(--hd-space-2); + } + + .hd-home-sample__icons-row.hd-home-sample__icons-extra-row { + display: none; + } +} + +.hd-home-sample__icons-row { + display: flex; + justify-content: space-between; +} + +.hd-home-samples .hd-home-sample__icons-icon { + color: var(--hop-neutral-icon-weak); +} + +.hd-home-samples .hd-home-sample__icons-icon--active { + color: var(--hop-primary-icon); +} + +.hd-home-samples .hd-home-sample__icons-icon--strong { + color: var(--hop-neutral-icon); +} + +/* Text Styles */ +.hd-home-sample__item-text-styles { + display: flex; + flex-direction: column; +} + +.hd-home-sample__text-styles { + border-bottom: 0; + border-image: linear-gradient(90deg,rgba(0 0 0 / 0%),rgb(186 188 192)) 1; + border-top: 0; + border-style: solid; + border-right: 0; + border-top-width: var(--hd-border-size); + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: var(--hd-space-3); + margin-top: var(--hd-space-3); +} + +@media screen and (width >= 37.5rem) { + .hd-home-sample__text-styles { + grid-template-columns: 1fr; + gap: var(--hd-space-1); + } +} + +@media screen and (width >= 44rem) { + .hd-home-sample__text-styles { + grid-template-columns: repeat(2, 1fr); + gap: var(--hd-space-3); + } +} + +.hd-home-sample__text { + font-family: Inter, sans-serif; + font-size: 5.25rem; + font-weight: 700; +} + +.hd-home-sample__text-lowercase { + color: transparent; + -webkit-text-stroke: 0.125rem var(--hd-color-neutral-text); +} + +.hd-home-sample__text-styles-col { + display: flex; + align-items: center; +} + +.hd-home-sample__text-styles-controls { + --background: var(--hd-white); + + align-items: start; + background-image: linear-gradient(180deg, var(--background) 0%, var(--background) 75%, rgba(255 255 255 / 0%) 100%); + border-bottom: 0; + border-image: linear-gradient(0deg, rgba(0 0 0 / 0%), rgb(186 188 192)) 1; + border-style: solid; + border-right: 0; + border-top: 0; + border-left-width: var(--hd-border-size); + display: grid; + flex-direction: column; + flex-grow: 1; + gap: 0.75rem; + padding: var(--hd-space-2); +} + +@media screen and (width >= 37.5rem) { + .hd-home-sample__text-styles-controls { + grid-template-columns: repeat(2, 1fr); + border-image: linear-gradient(90deg, rgba(0 0 0 / 0%), rgb(186 188 192)) 1; + border-style: solid; + border-top-width: var(--hd-border-size); + } +} + +@media screen and (width >= 44rem) { + .hd-home-sample__text-styles-controls { + grid-template-columns: 1fr; + border-image: linear-gradient(0deg, rgba(0 0 0 / 0%), rgb(186 188 192)) 1; + border-top: 0; + } +} + +[data-theme="dark"] .hd-home-sample__text-styles-controls { + --background: var(--hd-neutral-900); +} + +.hd-home-sample__control-knob { + align-items: center; + display: flex; + gap: 0.75rem; +} + +.hd-home-sample__control-knob-title { + align-items: center; + display: flex; + gap: 0.25rem; +} + +.hd-home-sample__control-knob-value { + color: var(--hd-color-neutral-text); + font-family: Arial, Helvetica, sans-serif; + font-size: 0.75rem; + line-height: 1; +} + +/* Text Styles - Control Text */ +.hd-home-sample__control-title { + font-family: Inter, sans-serif; + font-size: 0.75rem; + font-weight: 500; + line-height: 1.3333; +} + +/* Components */ +.hd-home-sample__item-components { + display: grid; + grid-template-rows: min-content min-content 1fr; +} + +.hd-home-sample-components { + display: grid; + grid-template-columns: 1fr; +} + +@media screen and (width >= 37.5rem) { + .hd-home-sample-components { + grid-template-columns: repeat(2, 1fr); + } +} + +@media screen and (width >= 62rem) { + .hd-home-sample-components { + grid-template-columns: repeat(4, 1fr); + } +} + +@media screen and (width >= 78.75rem) { + .hd-home-sample-components { + grid-template-columns: repeat(2, 1fr); + } +} + +.hd-home-sample-components__item-wrapper { + display: flex; +} + +.hd-home-sample-components__item { + --background: rgba(255 255 255 / 70%); + + align-items: center; + display: flex;; + flex-grow: 1; + justify-content: center; + padding: 1rem; +} + +@media screen and (width >= 78.75rem) { + .hd-home-sample-components__item-wrapper:nth-child(odd) { + background: linear-gradient(-90deg, var(--background) 0%, var(--background) 85%, rgba(0 212 255 / 0%) 100%); + border-bottom: 0; + border-image: linear-gradient(90deg,rgba(0 0 0 / 0%),rgb(186 188 192)) 1; + border-style: solid; + border-right: 0; + border-left: 0; + border-top-width: var(--hd-border-size); + } + + .hd-home-sample-components__item-wrapper:nth-child(even) { + background: linear-gradient(90deg, var(--background) 0%, var(--background) 85%, rgba(255 255 255 / 0%) 100%); + border-bottom: 0; + border-image: linear-gradient(-90deg,rgba(0 0 0 / 0%), rgb(186 188 192)) 1; + border-style: solid; + border-right: 0; + border-left: 0; + border-top-width: var(--hd-border-size); + } + + .hd-home-sample-components__item-wrapper:nth-child(2) .hd-home-sample-components__item { + border-bottom: 0; + border-image: linear-gradient(-90deg,rgba(0 0 0 / 0%), rgb(186 188 192)) 1; + border-style: solid; + border-right: 0; + border-left-width: var(--hd-border-size); + border-top: 0; + } + + .hd-home-sample-components__item-wrapper:nth-child(4) .hd-home-sample-components__item { + border-bottom: 0; + border-image: linear-gradient(0deg,rgba(0 0 0 / 0%) 0%, rgba(0 0 0 / 0%) 25%, rgb(186 188 192)) 1; + border-style: solid; + border-right: 0; + border-left-width: var(--hd-border-size); + border-top: 0; + } +} + +[data-theme="dark"] .hd-home-sample-components__item { + --background: rgba(41 41 41 / 70%); +} + +/* Components - Fake */ +.hd-home-sample-components__buttons { + display: flex; + gap: var(--hd-space-2); +} + +/* Upcoming */ +.hd-home-sample__item-upcoming { + background-image: linear-gradient(0deg, rgba(202 79 79 / 20%) 0%, rgba(60 60 60 / 50%) 75%); + border-radius: inherit; + display: flex; + inset: 0; + opacity: 0.1; + position: absolute; + z-index: 10; +} + +[data-theme="dark"] .hd-home-sample__item-upcoming { + background: linear-gradient(0deg, rgba(80 80 80 / 20%) 0%, rgba(80 80 80 / 60%) 75%); + opacity: 0.6; +} diff --git a/apps/docs/app/layout.css b/apps/docs/app/layout.css index 39952a4e7..ccc7c99b3 100644 --- a/apps/docs/app/layout.css +++ b/apps/docs/app/layout.css @@ -23,18 +23,12 @@ html { } main { - padding-block: var(--hd-space-4) var(--hd-space-8); + padding-block: var(--hd-space-8); flex: 1 1 auto; min-width: 0; order: 1; } -@media screen and (width >= 48rem) { - main { - padding-block-start: 0; - } -} - @media screen and (width >= 62rem) { .hd-container { flex-direction: row; @@ -42,7 +36,6 @@ main { main { order: 1; - padding-block-start: var(--hd-space-8); } } @@ -51,6 +44,10 @@ p { line-height: 1.5; } +.hd-content ul { + list-style-position: inside; +} + .hd-content p:not(:last-child) { margin-block-end: 1.25rem; } diff --git a/apps/docs/app/lib/contentConfig.ts b/apps/docs/app/lib/contentConfig.ts new file mode 100644 index 000000000..6def6e9ed --- /dev/null +++ b/apps/docs/app/lib/contentConfig.ts @@ -0,0 +1,5 @@ +/* `compileMDX` accepts a scope prop, which makes all of the values available for use in your MDX. + * Each key/value pair in the scope argument will be exposed as a javascript variable. + * So, for example, you could imagine if you had a scope like { foo: 'bar' }, it would be interpreted as const foo = 'bar'. + */ +export const data = {}; diff --git a/apps/docs/app/lib/getComponentCode.ts b/apps/docs/app/lib/getComponentCode.ts index 955604097..f0c8346e4 100644 --- a/apps/docs/app/lib/getComponentCode.ts +++ b/apps/docs/app/lib/getComponentCode.ts @@ -1,10 +1,6 @@ import path from "path"; import { promises as fs } from "fs"; -import { type Plugin, unified } from "unified"; -import remarkParse from "remark-parse"; -import remarkRehype from "remark-rehype"; -import rehypeStringify from "rehype-stringify"; -import { rehypePluginOptions } from "@/app/lib/rehypeConfig"; +import { highlightCode } from "@/components/highlightCode"; function formatComponentExamplePath(uri: string) { return path.join(process.cwd(), "..", "..", "packages", "components", "src", uri); @@ -22,17 +18,6 @@ ${code} `); } -async function highlightCode(code: string) { - const file = await unified() - .use(remarkParse as unknown as Plugin) - .use(remarkRehype as unknown as Plugin) - .use(rehypePluginOptions as unknown as Plugin) - .use(rehypeStringify as unknown as Plugin) - .process(code); - - return String(file); -} - export async function getComponentCode(filePath: string) { const examplePath = formatComponentExamplePath(filePath); const fileContent = await getFileContent(`${examplePath}.tsx`); diff --git a/apps/docs/app/lib/getComponentDetails.ts b/apps/docs/app/lib/getComponentDetails.ts index 5c74769b5..a99db4158 100644 --- a/apps/docs/app/lib/getComponentDetails.ts +++ b/apps/docs/app/lib/getComponentDetails.ts @@ -3,6 +3,7 @@ import fs from "fs"; import { compileMDX } from "next-mdx-remote/rsc"; import { components } from "@/components/mdx/components.tsx"; import { rehypePluginOptions } from "@/app/lib/rehypeConfig"; +import { data } from "@/app/lib/contentConfig.ts"; export const COMPONENT_PATH = path.join(process.cwd(), "content", "components"); @@ -15,6 +16,7 @@ async function parseFrontMatter(fileContent: string) { }>({ source: fileContent, options: { + scope: data, parseFrontmatter: true, mdxOptions: { remarkPlugins: [], rehypePlugins: rehypePluginOptions as unknown as [] } }, @@ -41,6 +43,7 @@ function getMDXData(dir: string) { const { frontmatter, content } = await readMDXFile(path.join(dir, file)); const slug = path.basename(file, path.extname(file)); + return { slug, frontmatter, diff --git a/apps/docs/app/pages/landing/page.tsx b/apps/docs/app/pages/landing/page.tsx new file mode 100644 index 000000000..bb0db0314 --- /dev/null +++ b/apps/docs/app/pages/landing/page.tsx @@ -0,0 +1,211 @@ +"use client"; + +import { Button as HopperButton, HopperProvider } from "@hopper-ui/components"; +import Image from "next/image"; +import { AccessibleIcon, ArrowIcon, DarkModeIcon, FontSizeIcon, InternationalIcon, LineHeightIcon, MarginIcon, SelectArrowIcon, TypescriptIcon } from "../../../components/icon/index"; +import { type ColorScheme, ThemeContext } from "@/context/theme/ThemeProvider.tsx"; +import { useContext } from "react"; +import Button from "@/components/button/Button"; +import Tag from "@/components/tag/Tag"; +import { ExternalLinkIcon, Icon } from "@/components/icon"; + +// eslint-disable-next-line max-len +import { CalendarIcon, ChartBarIcon, CheckmarkIcon, DeleteIcon, EyeVisibleIcon, FilterIcon, FocusIcon, ItalicIcon, LightbulbIcon, LockIcon, MailIcon, NotebookIcon, PinIcon, ProfileIcon, ReactionIcon, RecurringIcon, RewindIcon, SearchIcon, ShareIcon, StarIcon, StickyIcon, SyncIcon, TeamIcon, ThumbsUpIcon, UnarchiveIcon, WarningIcon } from "@hopper-ui/icons"; + +import "@hopper-ui/tokens/fonts.css"; +import "../../home.css"; + +export default function Home() { + const { colorMode } = useContext(ThemeContext); + + const theme = colorMode as ColorScheme; + + return ( +
+
+
+

Leap into creativity

+

Explore our Design System, where icons, tokens, and components are handpicked for ultimate simplicity and accessibility.

+
+
+ + +
+
+
+

Accessible

+

+ Built with accessibility in mind Hopper is based on React Aria Components +

+
+
+

International

+

+ Experience is pushed further with internationalization. +

+
+
+

Typescript

+

+ Typescript based for reduced learning curve and error detection. +

+
+
+

Dark mode

+

+ Switching from light to dark mode couldn't be easier. +

+
+
+
+
+
+ + +
+ +

Icons

+

A set of commonly used interface icons.

+ +
+ + + + + + + + + +
+
+ + + + + + + + + +
+
+ + + + + + + + + +
+
+
+
+
+
+
+

Components

+ upcoming +
+

An accessible suite of components powered by react-aria.

+
+
+
+ Avatar Group component preview +
+
+
+
+ Select Fielg component preview +
+
+
+
+ +
+ Confirm + I need help +
+
+
+
+
+
+ Radio Group Component preview +
+
+
+
+
+
+
+ ); +} diff --git a/apps/docs/app/tokens.css b/apps/docs/app/tokens.css index 6b7d4f2e3..415ae193a 100644 --- a/apps/docs/app/tokens.css +++ b/apps/docs/app/tokens.css @@ -89,7 +89,7 @@ [data-theme="dark"] { --hd-color-white-surface: var(--hd-neutral-800); --hd-color-neutral-surface: var(--hd-neutral-900); - --hd-color-neutral-surface-weak: var(--hd-neutral-800); + --hd-color-neutral-surface-weak: var(--hd-neutral-900); --hd-color-surface-neutral-selection: var(--hd-neutral-300); --hd-color-neutral-text: var(--hd-neutral-0); --hd-color-neutral-text-strong: var(--hd-neutral-900); diff --git a/apps/docs/app/ui/components/previewComponent/CodeWrapper.tsx b/apps/docs/app/ui/components/previewComponent/CodeWrapper.tsx index 67c4e33cd..b371d50cf 100644 --- a/apps/docs/app/ui/components/previewComponent/CodeWrapper.tsx +++ b/apps/docs/app/ui/components/previewComponent/CodeWrapper.tsx @@ -1,5 +1,5 @@ import { getComponentCode } from "@/app/lib/getComponentCode.ts"; -import CodeBlock from "@/app/ui/components/codeBlock/CodeBlock.tsx"; +import HighlightCode from "@/components/highlightCode/HighlightCode.tsx"; interface CodeWrapperProps { src: string; @@ -9,7 +9,7 @@ async function CodeWrapper({ src }: CodeWrapperProps) { const code = await getComponentCode(src); return ( - + ); } diff --git a/apps/docs/app/ui/components/previewComponent/previewComponent.css b/apps/docs/app/ui/components/previewComponent/previewComponent.css index b8661bbb3..73b5c28b8 100644 --- a/apps/docs/app/ui/components/previewComponent/previewComponent.css +++ b/apps/docs/app/ui/components/previewComponent/previewComponent.css @@ -26,7 +26,7 @@ .hd-component-wrapper__action { position: absolute; - inset: 1rem 1rem 0 auto; + inset: 1rem 1rem auto auto; z-index: 100; } diff --git a/apps/docs/app/ui/components/propTable/PropTable.tsx b/apps/docs/app/ui/components/propTable/PropTable.tsx new file mode 100644 index 000000000..ae885064a --- /dev/null +++ b/apps/docs/app/ui/components/propTable/PropTable.tsx @@ -0,0 +1,93 @@ +import { promises as fs } from "fs"; +import path from "path"; +import type { PropItem } from "react-docgen-typescript/lib/parser"; +import type { ComponentDocWithGroups } from "@/scripts/generateComponentData.mjs"; +import Collapsible from "@/components/collapsible/Collapsible.tsx"; +import Title from "@/components/title/Title.tsx"; + +import "./propTable.css"; + +export interface PropTableProps { + component: string; +} + +interface PropItemTypeValue { + name: string; + value?: Array<{ value: string; name: string }>; + raw?: string; +} + +const filePath = path.join(process.cwd(), "datas", "components"); + +const getType = (type: PropItemTypeValue) => { + const handler: { + [key: string]: (type: PropItemTypeValue) => string; + } = { + enum: t => + t.value ? t.value.map(item => item.value.replace(/'/g, "")).join(" \\| ") : "", + union: t => t.value ? t.value.map(item => item.name).join(" \\| ") : "" + }; + if (typeof handler[type.name] === "function") { + return handler[type.name](type).replace(/\|/g, ""); + } + + return type.name; +}; + +const renderRow = (key: string, prop: PropItem) => { + const { name, type, defaultValue, required, description } = prop; + + return ( + + {name} + {getType(type)} + {defaultValue?.value} + {required ? "✓" : "✗"} + {description} + + ); +}; + +export default async function PropTable({ component }: PropTableProps) { + const file = await fs.readFile(filePath + `/${component}.json`, "utf8"); + const data = JSON.parse(file); + + return data.map((item: ComponentDocWithGroups) => { + const { description, displayName, groups } = item; + + return ( + <> +

{displayName}

+

{description}

+ {Object.keys(groups).map(group => { + return ( + + {group} + + } + className="props__section" + > + + + + + + + + + + + + {Object.keys(groups[group]).map(key => renderRow(key, groups[group][key]))} + +
PropertyTypeDefaultRequiredDescription
+
+ ); + })} + + ); + }); +} diff --git a/apps/docs/app/ui/components/propTable/propTable.css b/apps/docs/app/ui/components/propTable/propTable.css new file mode 100644 index 000000000..578471498 --- /dev/null +++ b/apps/docs/app/ui/components/propTable/propTable.css @@ -0,0 +1,7 @@ +.props__section { + margin-top: var(--hd-space-1); +} + +.props__section .hd-collapsible__content { + margin-top: var(--hd-space-1); +} diff --git a/apps/docs/app/ui/layout/aside/aside.css b/apps/docs/app/ui/layout/aside/aside.css index 53d5f6607..0bf3b13c2 100644 --- a/apps/docs/app/ui/layout/aside/aside.css +++ b/apps/docs/app/ui/layout/aside/aside.css @@ -11,6 +11,10 @@ display: flex; padding-block-start: var(--hd-space-8); } + + .hd-aside + main { + padding-block-start: 0; + } } @media screen and (width >= 62rem) { @@ -23,6 +27,10 @@ top: var(--hd-space-8); height: calc(100vh - var(--hd-space-8)); } + + .hd-aside + main { + padding-block-start: var(--hd-space-8); + } } .hd-aside__list { @@ -50,7 +58,7 @@ /* making sure that if a user toggles the list and resize his browser the list is still visible */ /* We could do this in JS but I think that fixes the issue */ - display: flex!important; + display: flex !important; } .hd-aside__list--closed { @@ -109,7 +117,7 @@ left: 0; z-index: 1; border-radius: var(--hd-space-1); - transition: top .25s cubic-bezier(0,1,.5,1); + transition: top .25s cubic-bezier(0, 1, .5, 1); display: none; } diff --git a/apps/docs/app/ui/layout/header/header.css b/apps/docs/app/ui/layout/header/header.css index b07815403..3ebfe5f22 100644 --- a/apps/docs/app/ui/layout/header/header.css +++ b/apps/docs/app/ui/layout/header/header.css @@ -3,10 +3,22 @@ --hd-header-background-color: rgb(252 251 251 / 50%); --hd-header-border-color: var(--hd-color-neutral-border-weak); --hd-header-height: var(--hd-space-8); + --hd-header-shadow-1-block-color: rgba(175 182 225 / 80%); + --hd-header-shadow-2-block-color: #FECD94; + --hd-header-shadow-3-block-color: #A9F1D6; + --hd-header-shadow-1-top-position: -2.75rem; + --hd-header-shadow-2-top-position: -21.25rem; + --hd-header-shadow-3-top-position: -10.5rem; } [data-theme="dark"] { --hd-header-background-color: rgb(41 40 41 / 80%); + --hd-header-shadow-1-block-color: rgba(175 182 225 / 70%); + --hd-header-shadow-2-block-color: #FECD94; + --hd-header-shadow-3-block-color: #A9F1D6; + --hd-header-shadow-1-top-position: -18.75rem; + --hd-header-shadow-2-top-position: -31.25rem; + --hd-header-shadow-3-top-position: -19.5rem; } .hd-header { @@ -17,9 +29,18 @@ background-color: var(--hd-header-background-color); backdrop-filter: blur(1rem); border-block-end: var(--hd-border-size) solid var(--hd-header-border-color); + border-radius: 0 0 0.5rem 0.5rem; z-index: 999; } +@media screen and (width >= 37.5rem) { + .hd-header { + border-radius: 0.5rem; + margin: 1.5rem auto 0; + width: min(100% - 3rem, 75rem); + } +} + @media screen and (width >= 48rem) { .hd-header { position: sticky; @@ -85,25 +106,25 @@ } .hd-header-shadow-block-1 { - background-color: #AFB6E1; + background-color: var(--hd-header-shadow-1-block-color); width: 32rem; height: 32rem; - top: -18.75rem; + top: var(--hd-header-shadow-1-top-position); right: 6rem; } .hd-header-shadow-block-2 { width: 40rem; height: 40rem; - background-color: #FECD94; + background-color: var(--hd-header-shadow-2-block-color); filter: blur(12.5rem); - top: -31.25rem; + top: var(--hd-header-shadow-2-top-position); } .hd-header-shadow-block-3 { - background-color: #A9F1D6; + background-color: var(--hd-header-shadow-3-block-color); width: 32rem; height: 32rem; - top: -24rem; + top: var(--hd-header-shadow-3-top-position); left: -10.5rem; } diff --git a/apps/docs/app/ui/layout/nav/nav.css b/apps/docs/app/ui/layout/nav/nav.css index eb26c3e25..f93652df7 100644 --- a/apps/docs/app/ui/layout/nav/nav.css +++ b/apps/docs/app/ui/layout/nav/nav.css @@ -6,9 +6,9 @@ } .hd-nav { + display: none; font-size: var(--hd-nav-font-size); line-height: var(--hd-nav-line-height); - display: none; } @media screen and (width >= 37.5rem) { diff --git a/apps/docs/app/ui/tokens/preview/preview.css b/apps/docs/app/ui/tokens/preview/preview.css index 5d5fbcddf..cde6d319c 100644 --- a/apps/docs/app/ui/tokens/preview/preview.css +++ b/apps/docs/app/ui/tokens/preview/preview.css @@ -3,7 +3,9 @@ width: var(--hd-space-5); height: var(--hd-space-3); border-radius: 0; - float: right; + + /* float: right; */ + display: inline-block; background-color: var(--hd-color-primary-surface); } @@ -18,7 +20,7 @@ .hd-preview--font { align-items: center; background-color: transparent; - display: flex; + display: inline-flex; font-size: 1.5rem; height: auto; justify-content: flex-end; diff --git a/apps/docs/app/ui/tokens/table/IconSpecTable.tsx b/apps/docs/app/ui/tokens/table/IconSpecTable.tsx index e4b1368de..45042d04d 100644 --- a/apps/docs/app/ui/tokens/table/IconSpecTable.tsx +++ b/apps/docs/app/ui/tokens/table/IconSpecTable.tsx @@ -1,8 +1,6 @@ -"use client"; +import Table from "@/components/table/Table"; -import { Cell, Column, Row, Table as TableRA, TableBody, TableHeader } from "react-aria-components"; - -import "./table.css"; +import "./tokenTable.css"; interface IconSpecTableProps { data: { @@ -15,34 +13,11 @@ interface IconSpecTableProps { } const IconSpecTable = ({ data }: IconSpecTableProps) => { - const sizes = ["sm", "md", "lg"]; - - const listItems = data?.map(row => { - return ( - - {row.name} - {sizes.map(size => ( - - {row[size]} - - ))} - - ); - }); - - return ( - - - Anatomy - Small - Medium - Large - - - {listItems} - - - ); + return ; }; export default IconSpecTable; diff --git a/apps/docs/app/ui/tokens/table/Table.tsx b/apps/docs/app/ui/tokens/table/Table.tsx deleted file mode 100644 index d4ebe9621..000000000 --- a/apps/docs/app/ui/tokens/table/Table.tsx +++ /dev/null @@ -1,50 +0,0 @@ -"use client"; - -import { Cell, Column, Row, Table as TableRA, TableBody, TableHeader } from "react-aria-components"; - -import Preview from "@/app/ui/tokens/preview/Preview"; -import Code from "@/components/code/Code"; - -import "./table.css"; - -interface TableProps { - category: string; - noPreview?: boolean; - data: { - name: string; - value: string; - }[]; -} - -const Table = ({ category, data, noPreview }: TableProps) => { - const listItems = data?.map(token => { - const { name, value } = token; - - return ( - - - {`--${name}`} - - {value} - {!noPreview && - - } - - ); - }); - - return ( - - - Name - Value - {!noPreview && Preview} - - - {listItems} - - - ); -}; - -export default Table; diff --git a/apps/docs/app/ui/tokens/table/Table.stories.tsx b/apps/docs/app/ui/tokens/table/TokenTable.stories.tsx similarity index 80% rename from apps/docs/app/ui/tokens/table/Table.stories.tsx rename to apps/docs/app/ui/tokens/table/TokenTable.stories.tsx index 2aa8f577b..cd080f86c 100644 --- a/apps/docs/app/ui/tokens/table/Table.stories.tsx +++ b/apps/docs/app/ui/tokens/table/TokenTable.stories.tsx @@ -1,11 +1,11 @@ import type { Meta, StoryObj } from "@storybook/react"; -import Table from "./Table"; +import TokenTable from "./TokenTable.tsx"; const meta = { - title: "app/tokens/Table", - component: Table -} satisfies Meta; + title: "app/tokens/TokenTable", + component: TokenTable +} satisfies Meta; export default meta; type Story = StoryObj; diff --git a/apps/docs/app/ui/tokens/table/TokenTable.tsx b/apps/docs/app/ui/tokens/table/TokenTable.tsx new file mode 100644 index 000000000..8276385e3 --- /dev/null +++ b/apps/docs/app/ui/tokens/table/TokenTable.tsx @@ -0,0 +1,36 @@ +import Table from "@/components/table/Table"; + +import Preview from "@/app/ui/tokens/preview/Preview"; +import Code from "@/components/code/Code"; + +import "./tokenTable.css"; + +interface TableProps { + category: string; + noPreview?: boolean; + data: { + name: string; + value: string; + }[]; +} + +const TokenTable = ({ category, data, noPreview }: TableProps) => { + const formattedData = data.map(token => { + const { name, value } = token; + + return { + name: {`--${name}`}, + value: value, + preview: !noPreview && + }; + }); + + + return
; +}; + +export default TokenTable; diff --git a/apps/docs/app/ui/tokens/table/TypographyTable.tsx b/apps/docs/app/ui/tokens/table/TypographyTable.tsx index cbc5618ef..c9a2e68f6 100644 --- a/apps/docs/app/ui/tokens/table/TypographyTable.tsx +++ b/apps/docs/app/ui/tokens/table/TypographyTable.tsx @@ -1,11 +1,15 @@ -"use client"; - -import React from "react"; import clsx from "clsx"; -import { groupItemsByProperties, groupItemsByPropertiesAndSizes, type Size, type TokenData } from "@/app/lib/getTypographyTokens"; -import { TypographyTableRow } from "./TypographyTableRow"; +import Table from "@/components/table/Table"; + +import { + groupItemsByProperties, + groupItemsByPropertiesAndSizes, + type Size, + type TokenData +} from "@/app/lib/getTypographyTokens"; +import { typographyTableRow } from "./TypographyTableRow"; -import "./table.css"; +import "./tokenTable.css"; // maps the raw token list of a list filtered by property function transformDataToTokenData(inputData: Record): TokenData { @@ -31,36 +35,36 @@ const TypographyTable = ({ type, data }: TypographyTableProps) => { const hasNoSizes = type === "overline"; const tokenData = transformDataToTokenData(data); - const listItems = hasNoSizes ? generateSizelessRows(tokenData, type) : generateSizeRows(tokenData, type); + const listItems = hasNoSizes ? [generateSizelessRows(tokenData, type)] : generateSizeRows(tokenData, type); - return ( -
- - - {!hasNoSizes && } - - - - - - {listItems} - -
SizeValuesPreview
- ); + return (); }; function generateSizeRows(tokenData: TokenData, type: string) { const filteredData = groupItemsByPropertiesAndSizes(tokenData, type); return Object.keys(filteredData).map(size => { - return ; + return typographyTableRow( + type, + filteredData[size as keyof typeof filteredData]!, + size as Size + ); }); } function generateSizelessRows(tokenData: TokenData, type: string) { const properties = groupItemsByProperties(tokenData, type); - return ; + return typographyTableRow(type, properties!); } export default TypographyTable; diff --git a/apps/docs/app/ui/tokens/table/TypographyTableRow.tsx b/apps/docs/app/ui/tokens/table/TypographyTableRow.tsx index d8547b7d3..3e7fd31f6 100644 --- a/apps/docs/app/ui/tokens/table/TypographyTableRow.tsx +++ b/apps/docs/app/ui/tokens/table/TypographyTableRow.tsx @@ -2,15 +2,10 @@ import type { ComponentProps, ReactNode } from "react"; import TypographyPreview from "../preview/TypographyPreview"; import Code from "@/components/code/Code"; import type { FontProperties, Size } from "@/app/lib/getTypographyTokens"; -import "./table.css"; -interface TypographyTableRowProps { - type: string; - properties: FontProperties; - size?: Size; -} +import "./tokenTable.css"; -export function TypographyTableRow({ type, properties, size }: TypographyTableRowProps) { +export function typographyTableRow(type: string, properties: FontProperties, size?: Size) { const { fontFamily, fontSize, @@ -29,101 +24,97 @@ export function TypographyTableRow({ type, properties, size }: TypographyTableRo }; } - return ( - - {size && } - - - - ); + return ({ + name: size, + value: , + preview: + }); } interface PropertiesCellProps { properties: FontProperties; } -function PropertiesCell({ properties } : PropertiesCellProps) { +function PropertiesCell({ properties }: PropertiesCellProps) { return ( - +
{size} - -
- - - {properties.fontSize && ( - - )} - {properties.fontWeight && ( - - )} - {properties.lineHeight && ( - - )} - {properties.fontFamily && ( - - )} - {properties.topOffset && ( - Top Offset1} - value={properties.topOffset.value} - /> - )} - {properties.bottomOffset && ( - Bottom Offset1} - value={properties.bottomOffset.value} - /> - )} - -
-
+ + {properties.fontSize && ( + + )} + {properties.fontWeight && ( + + )} + {properties.lineHeight && ( + + )} + {properties.fontFamily && ( + + )} + {properties.topOffset && ( + Top Offset1} + value={properties.topOffset.value} + /> + )} + {properties.bottomOffset && ( + Bottom Offset1} + value={properties.bottomOffset.value} + /> + )} + +
); } -interface PropertyRowProps extends Omit, "children">{ +interface PropertyRowProps extends Omit, "children"> { tokenName: string; displayName: ReactNode; value: string; } function PropertyRow({ tokenName, displayName, value, ...rest }: PropertyRowProps) { - const tokenValue = value; - return ( @@ -133,7 +124,7 @@ function PropertyRow({ tokenName, displayName, value, ...rest }: PropertyRowProp {tokenName} - {tokenValue} + {value} ); diff --git a/apps/docs/app/ui/tokens/table/TypographyVariantTable.tsx b/apps/docs/app/ui/tokens/table/TypographyVariantTable.tsx index 0f9088dae..87f55ce1e 100644 --- a/apps/docs/app/ui/tokens/table/TypographyVariantTable.tsx +++ b/apps/docs/app/ui/tokens/table/TypographyVariantTable.tsx @@ -1,10 +1,8 @@ -"use client"; - -import React from "react"; import TypographyPreview from "@/app/ui/tokens/preview/TypographyPreview"; import Code from "@/components/code/Code"; +import Table from "@/components/table/Table"; -import "./table.css"; +import "./tokenTable.css"; interface TypographyVariantTableProps { data: Record; @@ -27,37 +25,20 @@ const TypographyVariantTable = ({ type, data }: TypographyVariantTableProps) => const listItems = filteredDataByWeightVariation.map(item => { const fontWeight = item.value; - return ( - - - {item.name} - - {`--${item.name}`} - - - {item.value} - - - - - - - ); + return { + name: {`--${item.name}`}, + value: fontWeight, + preview: + }; }); return ( - - - - - - - - - - {listItems} - -
NameValuePreview
+ ); }; diff --git a/apps/docs/app/ui/tokens/table/table.css b/apps/docs/app/ui/tokens/table/tokenTable.css similarity index 60% rename from apps/docs/app/ui/tokens/table/table.css rename to apps/docs/app/ui/tokens/table/tokenTable.css index cd275e8f4..56f42626e 100644 --- a/apps/docs/app/ui/tokens/table/table.css +++ b/apps/docs/app/ui/tokens/table/tokenTable.css @@ -1,44 +1,3 @@ -.hd-table { - width: 100%; - outline: none; - border-spacing: 0; - align-self: start; -} - -.hd-table__column { - padding: var(--hd-space-2) var(--hd-space-1); - text-align: left; - color: var(--hd-color-neutral-text-weakest); - font-size: 0.8125rem; - font-style: normal; - font-weight: 400; - line-height: 0.8125rem; -} - -.hd-table__column:first-child { - padding-left: 0; -} - -.hd-table__column:last-child, -.hd-table__cell:last-child { - text-align: right; -} - -.hd-table__column--size { - min-width: 3rem; -} - -.hd-table__cell { - font-family: var(--hd-mono-font-family); - font-size: 0.8125rem; - padding: var(--hd-space-1); - border-bottom: var(--hd-border-size) solid var(--hd-color-neutral-border); -} - -.hd-table__row > .hd-table__cell:first-child { - padding-left: 0; -} - /* TypoTable */ .hd-table__cell.hd-typo__cell { text-align: left; @@ -72,7 +31,7 @@ } /* Has No Sizes */ -.hd-typo-table--has-no-sizes .hd-typo__cell{ +.hd-typo-table--has-no-sizes .hd-typo__cell { padding: 0; } diff --git a/apps/docs/app/ui/tokens/tableSection/TableSection.tsx b/apps/docs/app/ui/tokens/tableSection/TableSection.tsx index 7ed27b1d0..b5d44607c 100644 --- a/apps/docs/app/ui/tokens/tableSection/TableSection.tsx +++ b/apps/docs/app/ui/tokens/tableSection/TableSection.tsx @@ -1,7 +1,7 @@ "use client"; import React from "react"; -import Table from "@/app/ui/tokens/table/Table"; +import TokenTable from "@/app/ui/tokens/table/TokenTable.tsx"; import "@hopper-ui/tokens/fonts.css"; @@ -25,7 +25,7 @@ const TableSection = ({ tokens, categories, excludedCategories, categoryKey }: T }); return
-
+ ; }; diff --git a/apps/docs/components/button/Button.stories.tsx b/apps/docs/components/button/Button.stories.tsx index 6dafae8ea..229c921dd 100644 --- a/apps/docs/components/button/Button.stories.tsx +++ b/apps/docs/components/button/Button.stories.tsx @@ -49,7 +49,6 @@ export const AsLink: Story = { as: "a", href: "https://www.npmjs.com/package/@hopper-ui/components", target: "_blank" - }, render: args => (
diff --git a/apps/docs/components/button/button.css b/apps/docs/components/button/button.css index 7a06b9555..9ad25469a 100644 --- a/apps/docs/components/button/button.css +++ b/apps/docs/components/button/button.css @@ -32,7 +32,8 @@ flex-direction: row-reverse; } -.hd-btn[data-focus-visible="true"] { +.hd-btn[data-focus-visible="true"], +a.hd-btn:focus-visible { box-shadow: var(--hd-focus-ring); } diff --git a/apps/docs/components/collapsible/Collapsible.stories.tsx b/apps/docs/components/collapsible/Collapsible.stories.tsx new file mode 100644 index 000000000..5f3d09385 --- /dev/null +++ b/apps/docs/components/collapsible/Collapsible.stories.tsx @@ -0,0 +1,19 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import Collasible from "./Collapsible.tsx"; + + +const meta = { + title: "components/Collasible", + component: Collasible +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + title: "Label", + children: "Conent of the collapsible" + } +}; diff --git a/apps/docs/components/collapsible/Collapsible.tsx b/apps/docs/components/collapsible/Collapsible.tsx new file mode 100644 index 000000000..169dc64de --- /dev/null +++ b/apps/docs/components/collapsible/Collapsible.tsx @@ -0,0 +1,52 @@ +"use client"; + +import clsx from "clsx"; +import { type ReactNode, useRef, useState } from "react"; +import { ToggleButton } from "react-aria-components"; +import { Icon, CollapseIcon } from "@/components/icon"; + +import "./collapsible.css"; + +export interface CollapsibleProps { + children: ReactNode; + title: ReactNode; + label?: string; + isOpen?: boolean; + className?: string; +} + +const Collapsible = ({ children, title, label, isOpen = false, className }: CollapsibleProps) => { + const [open, setOpen] = useState(isOpen); + const contentRef = useRef(null); + + let styles = { height: "0px" }; + + if (contentRef.current && open) { + styles = { height: contentRef.current.scrollHeight + "px" }; + } + + const toggle = () => { + setOpen(!open); + }; + + return ( +
+ + {title} + + +
+
{children}
+
+
+ ); +}; + +export default Collapsible; diff --git a/apps/docs/components/collapsible/collapsible.css b/apps/docs/components/collapsible/collapsible.css new file mode 100644 index 000000000..6d0282a60 --- /dev/null +++ b/apps/docs/components/collapsible/collapsible.css @@ -0,0 +1,52 @@ +/* Collapse */ +.hd-collapsible__trigger { + --collapsible-trigger-background: transparent; + + font-family: var(--hd-default-font-family); + font-size: var(--hd-default-font-size); + line-height: 1.35; + color: var(--hd-color-neutral-text); + display: flex; + width: 100%; + justify-content: space-between; + align-items: center; + padding-block: var(--hd-space-2); + padding-inline: var(--hd-space-2); + border: none; + border-radius: 0.5rem; + background: var(--collapsible-trigger-background); + box-shadow: none; + transition: box-shadow 0.15s ease-in-out; + margin-inline: calc(var(--hd-space-2) * -1); +} + +.hd-collapsible__trigger[data-hovered="true"] { + --collapsible-trigger-background: var(--hd-color-neutral-surface); + + cursor: pointer; + box-shadow: 0 0.25rem 0.625rem 0.25rem rgb(60 60 60 / 8%); +} + +.hd-collapsible__trigger .hd-title { + margin-block: 0; + margin-inline: 0; +} + +.hd-collapsible__trigger[data-focused="true"], +.hd-collapsible__trigger[data-focus-visible="true"] { + outline: none; +} + +.hd-collapsible__trigger[data-focus-visible="true"] { + box-shadow: var(--hd-focus-ring); +} + +.hd-collapsible__content { + padding-block: var(--hd-space-1); +} + +.hd-collapsible__content-parent { + height: 0; + overflow: hidden; + transition: height ease 0.15s; +} diff --git a/apps/docs/components/highlightCode/HighlightCode.stories.tsx b/apps/docs/components/highlightCode/HighlightCode.stories.tsx new file mode 100644 index 000000000..9dffa52c0 --- /dev/null +++ b/apps/docs/components/highlightCode/HighlightCode.stories.tsx @@ -0,0 +1,23 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import { HighlightCode, highlightCode } from "./"; + +const meta = { + title: "components/HighlightCode", + component: HighlightCode +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const code = await highlightCode(` +\`\`\`shell showLineNumbers +pnpm install @hoper-ui/icons +\`\`\` +`); + +export const Default: Story = { + args: { + code: code + } +}; diff --git a/apps/docs/app/ui/components/codeBlock/CodeBlock.tsx b/apps/docs/components/highlightCode/HighlightCode.tsx similarity index 86% rename from apps/docs/app/ui/components/codeBlock/CodeBlock.tsx rename to apps/docs/components/highlightCode/HighlightCode.tsx index 45ffda18b..a205881ac 100644 --- a/apps/docs/app/ui/components/codeBlock/CodeBlock.tsx +++ b/apps/docs/components/highlightCode/HighlightCode.tsx @@ -8,6 +8,10 @@ import rehypeParse from "rehype-parse"; import Pre from "@/components/pre/Pre.tsx"; +export interface HighlightCodeProps { + code: string; +} + const production = { Fragment: prod.Fragment, jsx: prod.jsx, jsxs: prod.jsxs, components: { pre: Pre } }; function useProcessor(text: string) { @@ -27,6 +31,6 @@ function useProcessor(text: string) { return Content; } -export default function CodeBlock({ code }: { code: string }) { +export default function HighlightCode({ code }: HighlightCodeProps) { return useProcessor(code); } diff --git a/apps/docs/components/highlightCode/highlightCode.ts b/apps/docs/components/highlightCode/highlightCode.ts new file mode 100644 index 000000000..a2593942d --- /dev/null +++ b/apps/docs/components/highlightCode/highlightCode.ts @@ -0,0 +1,16 @@ +import { type Plugin, unified } from "unified"; +import remarkParse from "remark-parse"; +import remarkRehype from "remark-rehype"; +import { rehypePluginOptions } from "@/app/lib/rehypeConfig"; +import rehypeStringify from "rehype-stringify"; + +export async function highlightCode(code: string) { + const file = await unified() + .use(remarkParse as unknown as Plugin) + .use(remarkRehype as unknown as Plugin) + .use(rehypePluginOptions as unknown as Plugin) + .use(rehypeStringify as unknown as Plugin) + .process(code); + + return String(file); +} diff --git a/apps/docs/components/highlightCode/index.ts b/apps/docs/components/highlightCode/index.ts new file mode 100644 index 000000000..ad98271c0 --- /dev/null +++ b/apps/docs/components/highlightCode/index.ts @@ -0,0 +1,8 @@ +import { highlightCode } from "./highlightCode.ts"; +import HighlightCode, { type HighlightCodeProps } from "./HighlightCode.tsx"; + +export { + highlightCode, + HighlightCode, + type HighlightCodeProps +}; diff --git a/apps/docs/components/icon/assets/accessible.svg b/apps/docs/components/icon/assets/accessible.svg new file mode 100644 index 000000000..dfeef8cf4 --- /dev/null +++ b/apps/docs/components/icon/assets/accessible.svg @@ -0,0 +1,4 @@ + + + + diff --git a/apps/docs/components/icon/assets/arrow.svg b/apps/docs/components/icon/assets/arrow.svg new file mode 100644 index 000000000..88f4a7332 --- /dev/null +++ b/apps/docs/components/icon/assets/arrow.svg @@ -0,0 +1 @@ + diff --git a/apps/docs/components/icon/assets/collapse.svg b/apps/docs/components/icon/assets/collapse.svg new file mode 100644 index 000000000..b69aec16d --- /dev/null +++ b/apps/docs/components/icon/assets/collapse.svg @@ -0,0 +1,6 @@ + + + + diff --git a/apps/docs/components/icon/assets/dark-mode.svg b/apps/docs/components/icon/assets/dark-mode.svg new file mode 100644 index 000000000..2eca64c38 --- /dev/null +++ b/apps/docs/components/icon/assets/dark-mode.svg @@ -0,0 +1 @@ + diff --git a/apps/docs/components/icon/assets/font-size.svg b/apps/docs/components/icon/assets/font-size.svg new file mode 100644 index 000000000..c90ece4a9 --- /dev/null +++ b/apps/docs/components/icon/assets/font-size.svg @@ -0,0 +1 @@ + diff --git a/apps/docs/components/icon/assets/international.svg b/apps/docs/components/icon/assets/international.svg new file mode 100644 index 000000000..364959b75 --- /dev/null +++ b/apps/docs/components/icon/assets/international.svg @@ -0,0 +1 @@ + diff --git a/apps/docs/components/icon/assets/line-height.svg b/apps/docs/components/icon/assets/line-height.svg new file mode 100644 index 000000000..76ce86cd7 --- /dev/null +++ b/apps/docs/components/icon/assets/line-height.svg @@ -0,0 +1 @@ + diff --git a/apps/docs/components/icon/assets/margin.svg b/apps/docs/components/icon/assets/margin.svg new file mode 100644 index 000000000..1a9f98949 --- /dev/null +++ b/apps/docs/components/icon/assets/margin.svg @@ -0,0 +1 @@ + diff --git a/apps/docs/components/icon/assets/select-arrow.svg b/apps/docs/components/icon/assets/select-arrow.svg new file mode 100644 index 000000000..736cf9ead --- /dev/null +++ b/apps/docs/components/icon/assets/select-arrow.svg @@ -0,0 +1 @@ + diff --git a/apps/docs/components/icon/assets/typescript.svg b/apps/docs/components/icon/assets/typescript.svg new file mode 100644 index 000000000..a1c9844d7 --- /dev/null +++ b/apps/docs/components/icon/assets/typescript.svg @@ -0,0 +1 @@ + diff --git a/apps/docs/components/icon/index.tsx b/apps/docs/components/icon/index.tsx index adfbb8eeb..7364279df 100644 --- a/apps/docs/components/icon/index.tsx +++ b/apps/docs/components/icon/index.tsx @@ -1,16 +1,36 @@ -import NpmIcon from "./assets/npm.svg"; -import GithubIcon from "./assets/github.svg"; -import ExternalLinkIcon from "./assets/external-link.svg"; +import AccessibleIcon from "./assets/accessible.svg"; +import ArrowIcon from "./assets/arrow.svg"; import ComponentIcon from "./assets/component.svg"; +import DarkModeIcon from "./assets/dark-mode.svg"; +import ExternalLinkIcon from "./assets/external-link.svg"; +import FontSizeIcon from "./assets/font-size.svg"; +import GithubIcon from "./assets/github.svg"; +import InternationalIcon from "./assets/international.svg"; +import LineHeightIcon from "./assets/line-height.svg"; +import MarginIcon from "./assets/margin.svg"; +import NpmIcon from "./assets/npm.svg"; +import SelectArrowIcon from "./assets/select-arrow.svg"; import TokenIcon from "./assets/tokens.svg"; +import TypescriptIcon from "./assets/typescript.svg"; +import CollapseIcon from "./assets/collapse.svg"; import Icon, { type IconProps } from "./Icon.tsx"; export { - Icon, - NpmIcon, - GithubIcon, - ExternalLinkIcon, + AccessibleIcon, + ArrowIcon, ComponentIcon, + DarkModeIcon, + ExternalLinkIcon, + FontSizeIcon, + GithubIcon, + InternationalIcon, + LineHeightIcon, + MarginIcon, + NpmIcon, + SelectArrowIcon, TokenIcon, + CollapseIcon, + TypescriptIcon, + Icon, IconProps }; diff --git a/apps/docs/components/mdx/components.tsx b/apps/docs/components/mdx/components.tsx index 0cc69939f..a3c0695c7 100644 --- a/apps/docs/components/mdx/components.tsx +++ b/apps/docs/components/mdx/components.tsx @@ -5,7 +5,7 @@ import Card from "@/components/card/Card.tsx"; import NextImage from "@/components/image/Image.tsx"; import Pre from "@/components/pre/Pre.tsx"; import InlineCode from "@/components/code/InlineCode.tsx"; -import Table from "@/app/ui/tokens/table/Table.tsx"; +import TokenTable from "@/app/ui/tokens/table/TokenTable.tsx"; import TypographyTable from "@/app/ui/tokens/table/TypographyTable.tsx"; import TypographyVariantTable from "@/app/ui/tokens/table/TypographyVariantTable.tsx"; import { IconTable } from "@/app/ui/icons/iconTable/IconTable.tsx"; @@ -16,13 +16,18 @@ import Switcher from "@/app/ui/icons/switcher/Switcher.tsx"; import Title from "@/components/title/Title.tsx"; import MotionPreview from "@/components/motionPreview/MotionPreview.tsx"; import Footnote from "@/components/footnote/Footnote.tsx"; +import PackageInstallation, { + type PackageInstallationProps +} from "@/components/packageInstallation/PackageInstallation.tsx"; import type { PreviewComponentProps } from "@/app/ui/components/previewComponent/PreviewComponent.tsx"; import type { MigrateGuideProps } from "@/app/ui/components/migrateGuide/MigrateGuide.tsx"; +import type { PropTableProps } from "@/app/ui/components/propTable/PropTable.tsx"; type HeadingProps = React.DetailedHTMLProps, HTMLHeadingElement>; const PreviewComponent = dynamic(() => import("@/app/ui/components/previewComponent/PreviewComponent.tsx")); const MigrateGuide = dynamic(() => import("@/app/ui/components/migrateGuide/MigrateGuide.tsx")); +const PropTable = dynamic(() => import("@/app/ui/components/propTable/PropTable.tsx")); export const components = { Card, @@ -31,7 +36,7 @@ export const components = { pre: Pre, MotionPreview: MotionPreview, Footnote: Footnote, - Table: Table, + Table: TokenTable, TypographyTable: TypographyTable, TypographyVariantTable: TypographyVariantTable, IconTable: IconTable, @@ -39,12 +44,18 @@ export const components = { Tabs: Tabs, TableSection: TableSection, Switcher: Switcher, + PackageInstallation: (props: PackageInstallationProps) => { + return ; + }, PreviewComponent: (props: PreviewComponentProps) => { return ; }, MigrateGuide: (props: MigrateGuideProps) => { return ; }, + PropTable: (props: PropTableProps) => { + return ; + }, h1: (props: HeadingProps) => { return ; }, diff --git a/apps/docs/components/packageInstallation/PackageInstallation.tsx b/apps/docs/components/packageInstallation/PackageInstallation.tsx new file mode 100644 index 000000000..45d1fc0d2 --- /dev/null +++ b/apps/docs/components/packageInstallation/PackageInstallation.tsx @@ -0,0 +1,75 @@ +import Tabs from "@/components/tabs/Tabs.tsx"; +import { HighlightCode, highlightCode } from "@/components/highlightCode"; + +import type { ReactElement } from "react"; + +export interface PackageInstallationProps { + library: string; + mode: "dev" | "prod"; +} + +type MethodIcons = Record<typeof methods[number], ReactElement>; + +const methods = ["pnpm", "yarn", "npm"] as const; + +const methodsIcons: MethodIcons = { + pnpm: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 156 156"> + <path fill="#F9AD00" + d="M48.78 48.78H0V0h48.78v48.78ZM102.44 48.78H53.66V0h48.78v48.78ZM156.1 48.78h-48.78V0h48.78v48.78Z" + /> + <path fill="#4E4E4E" d="M102.44 102.44H53.66V53.66h48.78v48.78Z" /> + <path fill="#F9AD00" d="M156.1 102.44h-48.78V53.66h48.78v48.78Z" /> + <path fill="#4E4E4E" + d="M48.78 156.1H0v-48.78h48.78v48.78ZM102.44 156.1H53.66v-48.78h48.78v48.78ZM156.1 156.1h-48.78v-48.78h48.78v48.78Z" + /> + </svg>, + yarn: <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256"> + <path fill="#368FB9" + d="M128 0C57.328 0 0 57.328 0 128s57.328 128 128 128 128-57.328 128-128S198.672 0 128 0" + /> + {/* eslint-disable max-len */} + <path fill="#FFF" + d="M203.317 174.06c-7.907 1.878-11.91 3.608-21.695 9.983-15.271 9.884-31.976 14.48-31.976 14.48s-1.383 2.076-5.387 3.015c-6.918 1.68-32.963 3.114-35.335 3.163-6.376.05-10.28-1.63-11.367-4.25-3.311-7.907 4.744-11.367 4.744-11.367s-1.779-1.087-2.817-2.076c-.939-.939-1.927-2.816-2.224-2.125-1.235 3.015-1.878 10.379-5.189 13.69-4.547 4.596-13.146 3.064-18.236.395-5.585-2.965.395-9.933.395-9.933s-3.015 1.779-5.436-1.878c-2.175-3.36-4.2-9.094-3.657-16.16.593-8.056 9.587-15.865 9.587-15.865s-1.581-11.91 3.608-24.117c4.695-11.12 17.347-20.065 17.347-20.065s-10.626-11.762-6.672-22.338c2.57-6.92 3.608-6.87 4.448-7.166 2.965-1.137 5.831-2.373 7.957-4.695 10.625-11.466 24.166-9.292 24.166-9.292s6.425-19.52 12.356-15.715c1.828 1.186 8.401 15.814 8.401 15.814s7.018-4.102 7.809-2.57c4.25 8.254 4.744 24.019 2.866 33.607-3.163 15.814-11.07 24.315-14.233 29.652-.741 1.236 8.5 5.14 14.332 21.3 5.387 14.777.593 27.182 1.433 28.566.148.247.198.346.198.346s6.177.494 18.582-7.166c6.622-4.102 14.48-8.698 23.425-8.797 8.65-.149 9.094 9.983 2.57 11.564zm11.763-7.265c-.89-7.017-6.82-11.86-14.431-11.762-11.367.148-20.905 6.03-27.231 9.934-2.471 1.532-4.596 2.669-6.425 3.509.395-5.733.05-13.245-2.916-21.498-3.608-9.885-8.45-15.963-11.91-19.472 4.003-5.832 9.489-14.332 12.058-27.478 2.224-11.219 1.533-28.664-3.558-38.45-1.038-1.976-2.767-3.41-4.942-4.003-.89-.247-2.57-.741-5.881.198-4.991-10.329-6.721-11.416-8.056-12.306-2.767-1.779-6.029-2.174-9.093-1.038-4.102 1.483-7.61 5.437-10.922 12.454a51.47 51.47 0 0 0-1.334 3.015c-6.277.445-16.161 2.718-24.513 11.762-1.038 1.137-3.064 1.977-5.19 2.768h.05c-4.349 1.532-6.326 5.09-8.747 11.515-3.361 8.994.098 17.84 3.508 23.574-4.645 4.151-10.823 10.773-14.084 18.532-4.053 9.588-4.498 18.978-4.35 24.068-3.459 3.658-8.796 10.527-9.39 18.237-.79 10.773 3.114 18.088 4.844 20.756.494.791 1.038 1.434 1.63 2.076-.197 1.334-.246 2.768.05 4.25.643 3.46 2.817 6.277 6.128 8.056 6.524 3.46 15.617 4.942 22.635 1.433 2.52 2.669 7.117 5.239 15.469 5.239h.494c2.125 0 29.109-1.433 36.967-3.36 3.509-.841 5.93-2.324 7.512-3.658 5.04-1.582 18.977-6.326 32.123-14.826 9.291-6.03 12.504-7.315 19.423-8.995 6.72-1.63 10.922-7.759 10.082-14.53z" + /> + </svg>, + npm: <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256"> + <path fill="#C12127" d="M0 256V0h256v256z" /> + <path fill="#FFF" d="M48 48h160v160h-32V80h-48v128H48z" /> + </svg> +}; + +const installMethods = methods.map(method => ({ + category: method, + title: method, + titleIcon: methodsIcons[method] +})); + +const formatCode = async (method: string, library: string, mode: string) => { + const code = `${method} add ${mode === "dev" ? "-D" : ""} @hopper-ui/${library}`; + + return await highlightCode(` +\`\`\`shell +${code.replace(/\s{2,}/g, " ")} +\`\`\` +`); +}; + +const PackageInstallation = async ({ library, mode = "prod" }: PackageInstallationProps) => { + const tabsContent = await Promise.all(methods.map(async method => { + const code = await formatCode(method, library, mode); + + return ( + <div key={method}> + <HighlightCode code={code} /> + </div> + ); + })); + + return ( + <Tabs tabs={installMethods}> + {tabsContent} + </Tabs> + ); +}; + +export default PackageInstallation; diff --git a/apps/docs/components/pre/pre.css b/apps/docs/components/pre/pre.css index 205c1e549..2e927d20e 100644 --- a/apps/docs/components/pre/pre.css +++ b/apps/docs/components/pre/pre.css @@ -8,6 +8,7 @@ margin-block: 0.25rem; align-content: center; color: var(--hd-color-neutral-text-strong); + overflow-x: auto; } .hd-pre--title, diff --git a/apps/docs/components/table/Table.stories.tsx b/apps/docs/components/table/Table.stories.tsx new file mode 100644 index 000000000..71eba3345 --- /dev/null +++ b/apps/docs/components/table/Table.stories.tsx @@ -0,0 +1,50 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import Table from "./Table"; +import Code from "@/components/code/Code"; +import Preview from "@/app/ui/tokens/preview/Preview.tsx"; + +const meta = { + title: "components/Table", + component: Table +} satisfies Meta<typeof Table>; + +export default meta; +type Story = StoryObj<typeof meta>; + +export const Default: Story = { + args: { + head: ["Position", "Mass", "Symbol", "Name"], + data: [ + { position: 6, mass: 12.011, symbol: "C", name: "Carbon" }, + { position: 7, mass: 14.007, symbol: "N", name: "Nitrogen" }, + { position: 39, mass: 88.906, symbol: "Y", name: "Yttrium" }, + { position: 56, mass: 137.33, symbol: "Ba", name: "Barium" }, + { position: 58, mass: 140.12, symbol: "Ce", name: "Cerium" } + ] + } +}; + +export const Tokens: Story = { + args: { + lastColumnAlignment: "right", + head: ["Token", "Value", "Preview"], + data: [ + { + name: <Code value="--hop-sapphire-200">--hop-sapphire-200</Code>, + value: "#95b1ff", + preview: <Preview value="#95b1ff" name="--hop-sapphire-200" category="react" /> + }, + { + name: <Code value="--hop-primary-surface-disabled">--hop-primary-surface-disabled</Code>, + value: "#95b1ff", + preview: <Preview value="#95b1ff" name="--hop-primary-surface-disabled" category="react" /> + }, + { + name: <Code value="--hop-primary-surface-disabled">--hop-primary-surface-disabled</Code>, + value: "#2040c7", + preview: <Preview value="#2040c7" name="--hop-primary-surface-disabled" category="react" /> + } + ] + } +}; diff --git a/apps/docs/components/table/Table.tsx b/apps/docs/components/table/Table.tsx new file mode 100644 index 000000000..9a84d3db0 --- /dev/null +++ b/apps/docs/components/table/Table.tsx @@ -0,0 +1,68 @@ +"use client"; + +import clsx from "clsx"; +import { Cell, Column, Row, Table as TableRA, TableBody, TableHeader } from "react-aria-components"; +import type { ReactNode } from "react"; + +import "./table.css"; + +interface dataType { + [key: string]: string | number | boolean | undefined | null | ReactNode; +} + +interface TableProps { + head: (string | boolean)[]; + data: dataType[]; + lastColumnAlignment?: "left" | "right"; + "ariaLabel"?: string; + className?: string; +} + +function generateUniqueKey() { + return `${Date.now()}-${Math.random()}`; +} + +const Table = ({ data, head, lastColumnAlignment = "left", ariaLabel = "standard table", className }: TableProps) => { + const textAlignRight = lastColumnAlignment === "right"; + const lastColumn = head.length - 1; + + const headItems = head.map((item, index) => { + return ( + <Column isRowHeader + key={`table-body-${generateUniqueKey()}`} + className={clsx("hd-table__column", { "hd-table__colum--right": index === lastColumn && textAlignRight })} + > + {item} + </Column> + ); + }); + + const dataItems = data.map(item => { + return ( + <Row key={`table-body-${generateUniqueKey()}`} className="hd-table__row"> + {Object.keys(item).map((key, index) => { + return ( + <Cell key={key} + className={clsx("hd-table__cell", { "hd-table__cell--right": index === lastColumn && textAlignRight })} + > + {item[key]} + </Cell> + ); + })} + </Row> + ); + }); + + return ( + <TableRA className={clsx("hd-table", className)} aria-label={ariaLabel}> + <TableHeader> + {headItems} + </TableHeader> + <TableBody> + {dataItems} + </TableBody> + </TableRA> + ); +}; + +export default Table; diff --git a/apps/docs/components/table/table.css b/apps/docs/components/table/table.css new file mode 100644 index 000000000..195fba20c --- /dev/null +++ b/apps/docs/components/table/table.css @@ -0,0 +1,40 @@ +.hd-table { + width: 100%; + outline: none; + border-spacing: 0; + align-self: start; +} + +.hd-table__column { + padding: var(--hd-space-2) var(--hd-space-1); + text-align: left; + color: var(--hd-color-neutral-text-weakest); + font-size: 0.8125rem; + font-style: normal; + font-weight: 400; + line-height: 0.8125rem; +} + +.hd-table__column:first-child { + padding-left: 0; +} + +.hd-table__column--size { + min-width: 3rem; +} + +.hd-table__cell { + font-family: var(--hd-mono-font-family); + font-size: 0.8125rem; + padding: var(--hd-space-1); + border-bottom: var(--hd-border-size) solid var(--hd-color-neutral-border); +} + +.hd-table__row > .hd-table__cell:first-child { + padding-left: 0; +} + +.hd-table__colum--right, +.hd-table__cell--right { + text-align: right; +} diff --git a/apps/docs/components/themeSwitch/themeSwitch.css b/apps/docs/components/themeSwitch/themeSwitch.css index 82e247791..60b3b9abf 100644 --- a/apps/docs/components/themeSwitch/themeSwitch.css +++ b/apps/docs/components/themeSwitch/themeSwitch.css @@ -10,7 +10,7 @@ font-size: 1rem; } -@media screen and (width >= 48rem) { +@media screen and (width >= 37.5rem) { .hd-theme-switch__button { width: var(--hd-space-4); aspect-ratio: 1/1; diff --git a/apps/docs/content/components/button.mdx b/apps/docs/content/components/button.mdx index 7c253f9dc..d7c844de4 100644 --- a/apps/docs/content/components/button.mdx +++ b/apps/docs/content/components/button.mdx @@ -17,6 +17,10 @@ import { Button } from "@hopper-ui/components"; ```tsx showLineNumbers <Button>save</Button> ``` +## Props +The table below contains all types of the props available in title component. + +<PropTable component="Button" /> ## Migration Notes <MigrateGuide src="buttons/docs/migration-notes" /> diff --git a/apps/docs/content/components/installation.mdx b/apps/docs/content/components/installation.mdx index 50d842110..acea6300e 100644 --- a/apps/docs/content/components/installation.mdx +++ b/apps/docs/content/components/installation.mdx @@ -4,3 +4,7 @@ description: The installation proccess --- # Installation + +## Install packages + +<PackageInstallation library="components" mod="prod" /> diff --git a/apps/docs/content/icons/react-icons/icon-library.mdx b/apps/docs/content/icons/react-icons/icon-library.mdx index cdc54e9da..907318784 100644 --- a/apps/docs/content/icons/react-icons/icon-library.mdx +++ b/apps/docs/content/icons/react-icons/icon-library.mdx @@ -9,6 +9,8 @@ export const usageMethods = [ { title: "SVG" } ]; +# Icons + All available icons in the icon library are shown below. Use the correct size for each icon. Icons should be used at their original size according to the design. diff --git a/apps/docs/content/icons/react-icons/installation.mdx b/apps/docs/content/icons/react-icons/installation.mdx index a84606049..ca1cd8255 100644 --- a/apps/docs/content/icons/react-icons/installation.mdx +++ b/apps/docs/content/icons/react-icons/installation.mdx @@ -4,12 +4,6 @@ description: Getting started with Workleap Design Icons order: 1 --- -export const installMethods = [ - { title: "pnpm", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 156 156"><path fill="#F9AD00" d="M48.78 48.78H0V0h48.78v48.78ZM102.44 48.78H53.66V0h48.78v48.78ZM156.1 48.78h-48.78V0h48.78v48.78Z"/><path fill="#4E4E4E" d="M102.44 102.44H53.66V53.66h48.78v48.78Z"/><path fill="#F9AD00" d="M156.1 102.44h-48.78V53.66h48.78v48.78Z"/><path fill="#4E4E4E" d="M48.78 156.1H0v-48.78h48.78v48.78ZM102.44 156.1H53.66v-48.78h48.78v48.78ZM156.1 156.1h-48.78v-48.78h48.78v48.78Z"/></svg>}, - { title: "yarn", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256"><path fill="#368FB9" d="M128 0C57.328 0 0 57.328 0 128s57.328 128 128 128 128-57.328 128-128S198.672 0 128 0"/><path fill="#FFF" d="M203.317 174.06c-7.907 1.878-11.91 3.608-21.695 9.983-15.271 9.884-31.976 14.48-31.976 14.48s-1.383 2.076-5.387 3.015c-6.918 1.68-32.963 3.114-35.335 3.163-6.376.05-10.28-1.63-11.367-4.25-3.311-7.907 4.744-11.367 4.744-11.367s-1.779-1.087-2.817-2.076c-.939-.939-1.927-2.816-2.224-2.125-1.235 3.015-1.878 10.379-5.189 13.69-4.547 4.596-13.146 3.064-18.236.395-5.585-2.965.395-9.933.395-9.933s-3.015 1.779-5.436-1.878c-2.175-3.36-4.2-9.094-3.657-16.16.593-8.056 9.587-15.865 9.587-15.865s-1.581-11.91 3.608-24.117c4.695-11.12 17.347-20.065 17.347-20.065s-10.626-11.762-6.672-22.338c2.57-6.92 3.608-6.87 4.448-7.166 2.965-1.137 5.831-2.373 7.957-4.695 10.625-11.466 24.166-9.292 24.166-9.292s6.425-19.52 12.356-15.715c1.828 1.186 8.401 15.814 8.401 15.814s7.018-4.102 7.809-2.57c4.25 8.254 4.744 24.019 2.866 33.607-3.163 15.814-11.07 24.315-14.233 29.652-.741 1.236 8.5 5.14 14.332 21.3 5.387 14.777.593 27.182 1.433 28.566.148.247.198.346.198.346s6.177.494 18.582-7.166c6.622-4.102 14.48-8.698 23.425-8.797 8.65-.149 9.094 9.983 2.57 11.564zm11.763-7.265c-.89-7.017-6.82-11.86-14.431-11.762-11.367.148-20.905 6.03-27.231 9.934-2.471 1.532-4.596 2.669-6.425 3.509.395-5.733.05-13.245-2.916-21.498-3.608-9.885-8.45-15.963-11.91-19.472 4.003-5.832 9.489-14.332 12.058-27.478 2.224-11.219 1.533-28.664-3.558-38.45-1.038-1.976-2.767-3.41-4.942-4.003-.89-.247-2.57-.741-5.881.198-4.991-10.329-6.721-11.416-8.056-12.306-2.767-1.779-6.029-2.174-9.093-1.038-4.102 1.483-7.61 5.437-10.922 12.454a51.47 51.47 0 0 0-1.334 3.015c-6.277.445-16.161 2.718-24.513 11.762-1.038 1.137-3.064 1.977-5.19 2.768h.05c-4.349 1.532-6.326 5.09-8.747 11.515-3.361 8.994.098 17.84 3.508 23.574-4.645 4.151-10.823 10.773-14.084 18.532-4.053 9.588-4.498 18.978-4.35 24.068-3.459 3.658-8.796 10.527-9.39 18.237-.79 10.773 3.114 18.088 4.844 20.756.494.791 1.038 1.434 1.63 2.076-.197 1.334-.246 2.768.05 4.25.643 3.46 2.817 6.277 6.128 8.056 6.524 3.46 15.617 4.942 22.635 1.433 2.52 2.669 7.117 5.239 15.469 5.239h.494c2.125 0 29.109-1.433 36.967-3.36 3.509-.841 5.93-2.324 7.512-3.658 5.04-1.582 18.977-6.326 32.123-14.826 9.291-6.03 12.504-7.315 19.423-8.995 6.72-1.63 10.922-7.759 10.082-14.53z"/></svg> }, - { title: "npm", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256"><path fill="#C12127" d="M0 256V0h256v256z"/><path fill="#FFF" d="M48 48h160v160h-32V80h-48v128H48z"/></svg> } -]; - React Icons are typically utilized alongside the `@hopper-ui/components`. If you want to use them without `@hopper-ui/components`, refer to the [standalone installation](/icons/react-icons/standalone-installation). ## Prerequisites @@ -18,23 +12,7 @@ Follow the `@hopper-ui/components` procedure(coming soon). ## Install packages -<Tabs tabs={installMethods}> - <div> - ```shell - pnpm add @hopper-ui/icons - ``` - </div> - <div> - ```shell - yarn add -D @hopper-ui/icons - ``` - </div> - <div> - ```shell - npm add -D @hopper-ui/icons - ``` - </div> -</Tabs> +<PackageInstallation library="icons" mod="prod" /> ## Import Styles diff --git a/apps/docs/content/icons/react-icons/standalone-installation.mdx b/apps/docs/content/icons/react-icons/standalone-installation.mdx index 47dc149ef..8562b7a98 100644 --- a/apps/docs/content/icons/react-icons/standalone-installation.mdx +++ b/apps/docs/content/icons/react-icons/standalone-installation.mdx @@ -4,33 +4,11 @@ description: Getting started with Workleap Design Icons order: 2 --- -export const installMethods = [ - { title: "pnpm", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 156 156"><path fill="#F9AD00" d="M48.78 48.78H0V0h48.78v48.78ZM102.44 48.78H53.66V0h48.78v48.78ZM156.1 48.78h-48.78V0h48.78v48.78Z"/><path fill="#4E4E4E" d="M102.44 102.44H53.66V53.66h48.78v48.78Z"/><path fill="#F9AD00" d="M156.1 102.44h-48.78V53.66h48.78v48.78Z"/><path fill="#4E4E4E" d="M48.78 156.1H0v-48.78h48.78v48.78ZM102.44 156.1H53.66v-48.78h48.78v48.78ZM156.1 156.1h-48.78v-48.78h48.78v48.78Z"/></svg>}, - { title: "yarn", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256"><path fill="#368FB9" d="M128 0C57.328 0 0 57.328 0 128s57.328 128 128 128 128-57.328 128-128S198.672 0 128 0"/><path fill="#FFF" d="M203.317 174.06c-7.907 1.878-11.91 3.608-21.695 9.983-15.271 9.884-31.976 14.48-31.976 14.48s-1.383 2.076-5.387 3.015c-6.918 1.68-32.963 3.114-35.335 3.163-6.376.05-10.28-1.63-11.367-4.25-3.311-7.907 4.744-11.367 4.744-11.367s-1.779-1.087-2.817-2.076c-.939-.939-1.927-2.816-2.224-2.125-1.235 3.015-1.878 10.379-5.189 13.69-4.547 4.596-13.146 3.064-18.236.395-5.585-2.965.395-9.933.395-9.933s-3.015 1.779-5.436-1.878c-2.175-3.36-4.2-9.094-3.657-16.16.593-8.056 9.587-15.865 9.587-15.865s-1.581-11.91 3.608-24.117c4.695-11.12 17.347-20.065 17.347-20.065s-10.626-11.762-6.672-22.338c2.57-6.92 3.608-6.87 4.448-7.166 2.965-1.137 5.831-2.373 7.957-4.695 10.625-11.466 24.166-9.292 24.166-9.292s6.425-19.52 12.356-15.715c1.828 1.186 8.401 15.814 8.401 15.814s7.018-4.102 7.809-2.57c4.25 8.254 4.744 24.019 2.866 33.607-3.163 15.814-11.07 24.315-14.233 29.652-.741 1.236 8.5 5.14 14.332 21.3 5.387 14.777.593 27.182 1.433 28.566.148.247.198.346.198.346s6.177.494 18.582-7.166c6.622-4.102 14.48-8.698 23.425-8.797 8.65-.149 9.094 9.983 2.57 11.564zm11.763-7.265c-.89-7.017-6.82-11.86-14.431-11.762-11.367.148-20.905 6.03-27.231 9.934-2.471 1.532-4.596 2.669-6.425 3.509.395-5.733.05-13.245-2.916-21.498-3.608-9.885-8.45-15.963-11.91-19.472 4.003-5.832 9.489-14.332 12.058-27.478 2.224-11.219 1.533-28.664-3.558-38.45-1.038-1.976-2.767-3.41-4.942-4.003-.89-.247-2.57-.741-5.881.198-4.991-10.329-6.721-11.416-8.056-12.306-2.767-1.779-6.029-2.174-9.093-1.038-4.102 1.483-7.61 5.437-10.922 12.454a51.47 51.47 0 0 0-1.334 3.015c-6.277.445-16.161 2.718-24.513 11.762-1.038 1.137-3.064 1.977-5.19 2.768h.05c-4.349 1.532-6.326 5.09-8.747 11.515-3.361 8.994.098 17.84 3.508 23.574-4.645 4.151-10.823 10.773-14.084 18.532-4.053 9.588-4.498 18.978-4.35 24.068-3.459 3.658-8.796 10.527-9.39 18.237-.79 10.773 3.114 18.088 4.844 20.756.494.791 1.038 1.434 1.63 2.076-.197 1.334-.246 2.768.05 4.25.643 3.46 2.817 6.277 6.128 8.056 6.524 3.46 15.617 4.942 22.635 1.433 2.52 2.669 7.117 5.239 15.469 5.239h.494c2.125 0 29.109-1.433 36.967-3.36 3.509-.841 5.93-2.324 7.512-3.658 5.04-1.582 18.977-6.326 32.123-14.826 9.291-6.03 12.504-7.315 19.423-8.995 6.72-1.63 10.922-7.759 10.082-14.53z"/></svg> }, - { title: "npm", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256"><path fill="#C12127" d="M0 256V0h256v256z"/><path fill="#FFF" d="M48 48h160v160h-32V80h-48v128H48z"/></svg> } -]; - It is recommended to use `@hopper-ui/icons` with `@hopper-ui/components` as detailed in the [installation section](/icons/react-icons/installation). The standalone installation procedure is detailed in case you only need the icons, and not the components. ## Install packages -<Tabs tabs={installMethods}> - <div> - ```shell - pnpm add @hopper-ui/icons @hopper-ui/styled-system react-aria-components - ``` - </div> - <div> - ```shell - yarn add @hopper-ui/icons @hopper-ui/styled-system react-aria-components - ``` - </div> - <div> - ```shell - npm add @hopper-ui/icons @hopper-ui/styled-system react-aria-components - ``` - </div> -</Tabs> +<PackageInstallation library="icons @hopper-ui/styled-system react-aria-components" mod="prod" /> ## Import Styles diff --git a/apps/docs/content/icons/svg/installation.mdx b/apps/docs/content/icons/svg/installation.mdx index 2f922ed08..36083ff9a 100644 --- a/apps/docs/content/icons/svg/installation.mdx +++ b/apps/docs/content/icons/svg/installation.mdx @@ -4,31 +4,9 @@ description: Getting started with Workleap Design Icons order: 1 --- -export const installMethods = [ - { title: "pnpm", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 156 156"><path fill="#F9AD00" d="M48.78 48.78H0V0h48.78v48.78ZM102.44 48.78H53.66V0h48.78v48.78ZM156.1 48.78h-48.78V0h48.78v48.78Z"/><path fill="#4E4E4E" d="M102.44 102.44H53.66V53.66h48.78v48.78Z"/><path fill="#F9AD00" d="M156.1 102.44h-48.78V53.66h48.78v48.78Z"/><path fill="#4E4E4E" d="M48.78 156.1H0v-48.78h48.78v48.78ZM102.44 156.1H53.66v-48.78h48.78v48.78ZM156.1 156.1h-48.78v-48.78h48.78v48.78Z"/></svg>}, - { title: "yarn", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256"><path fill="#368FB9" d="M128 0C57.328 0 0 57.328 0 128s57.328 128 128 128 128-57.328 128-128S198.672 0 128 0"/><path fill="#FFF" d="M203.317 174.06c-7.907 1.878-11.91 3.608-21.695 9.983-15.271 9.884-31.976 14.48-31.976 14.48s-1.383 2.076-5.387 3.015c-6.918 1.68-32.963 3.114-35.335 3.163-6.376.05-10.28-1.63-11.367-4.25-3.311-7.907 4.744-11.367 4.744-11.367s-1.779-1.087-2.817-2.076c-.939-.939-1.927-2.816-2.224-2.125-1.235 3.015-1.878 10.379-5.189 13.69-4.547 4.596-13.146 3.064-18.236.395-5.585-2.965.395-9.933.395-9.933s-3.015 1.779-5.436-1.878c-2.175-3.36-4.2-9.094-3.657-16.16.593-8.056 9.587-15.865 9.587-15.865s-1.581-11.91 3.608-24.117c4.695-11.12 17.347-20.065 17.347-20.065s-10.626-11.762-6.672-22.338c2.57-6.92 3.608-6.87 4.448-7.166 2.965-1.137 5.831-2.373 7.957-4.695 10.625-11.466 24.166-9.292 24.166-9.292s6.425-19.52 12.356-15.715c1.828 1.186 8.401 15.814 8.401 15.814s7.018-4.102 7.809-2.57c4.25 8.254 4.744 24.019 2.866 33.607-3.163 15.814-11.07 24.315-14.233 29.652-.741 1.236 8.5 5.14 14.332 21.3 5.387 14.777.593 27.182 1.433 28.566.148.247.198.346.198.346s6.177.494 18.582-7.166c6.622-4.102 14.48-8.698 23.425-8.797 8.65-.149 9.094 9.983 2.57 11.564zm11.763-7.265c-.89-7.017-6.82-11.86-14.431-11.762-11.367.148-20.905 6.03-27.231 9.934-2.471 1.532-4.596 2.669-6.425 3.509.395-5.733.05-13.245-2.916-21.498-3.608-9.885-8.45-15.963-11.91-19.472 4.003-5.832 9.489-14.332 12.058-27.478 2.224-11.219 1.533-28.664-3.558-38.45-1.038-1.976-2.767-3.41-4.942-4.003-.89-.247-2.57-.741-5.881.198-4.991-10.329-6.721-11.416-8.056-12.306-2.767-1.779-6.029-2.174-9.093-1.038-4.102 1.483-7.61 5.437-10.922 12.454a51.47 51.47 0 0 0-1.334 3.015c-6.277.445-16.161 2.718-24.513 11.762-1.038 1.137-3.064 1.977-5.19 2.768h.05c-4.349 1.532-6.326 5.09-8.747 11.515-3.361 8.994.098 17.84 3.508 23.574-4.645 4.151-10.823 10.773-14.084 18.532-4.053 9.588-4.498 18.978-4.35 24.068-3.459 3.658-8.796 10.527-9.39 18.237-.79 10.773 3.114 18.088 4.844 20.756.494.791 1.038 1.434 1.63 2.076-.197 1.334-.246 2.768.05 4.25.643 3.46 2.817 6.277 6.128 8.056 6.524 3.46 15.617 4.942 22.635 1.433 2.52 2.669 7.117 5.239 15.469 5.239h.494c2.125 0 29.109-1.433 36.967-3.36 3.509-.841 5.93-2.324 7.512-3.658 5.04-1.582 18.977-6.326 32.123-14.826 9.291-6.03 12.504-7.315 19.423-8.995 6.72-1.63 10.922-7.759 10.082-14.53z"/></svg> }, - { title: "npm", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256"><path fill="#C12127" d="M0 256V0h256v256z"/><path fill="#FFF" d="M48 48h160v160h-32V80h-48v128H48z"/></svg> } -]; - ## Install packages -<Tabs tabs={installMethods}> - <div> - ```shell - pnpm add @hopper-ui/svg-icons - ``` - </div> - <div> - ```shell - yarn add -D @hopper-ui/svg-icons - ``` - </div> - <div> - ```shell - npm add -D @hopper-ui/svg-icons - ``` - </div> -</Tabs> +<PackageInstallation library="svg-icons" mod="prod" /> ## Start using icons diff --git a/apps/docs/content/tokens/getting-started/installation.mdx b/apps/docs/content/tokens/getting-started/installation.mdx index 54a4ee9f7..19d9edb30 100644 --- a/apps/docs/content/tokens/getting-started/installation.mdx +++ b/apps/docs/content/tokens/getting-started/installation.mdx @@ -4,30 +4,8 @@ description: Getting started with Workleap Design Tokens order: 2 --- -export const installMethods = [ - { title: "pnpm", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 156 156"><path fill="#F9AD00" d="M48.78 48.78H0V0h48.78v48.78ZM102.44 48.78H53.66V0h48.78v48.78ZM156.1 48.78h-48.78V0h48.78v48.78Z"/><path fill="#4E4E4E" d="M102.44 102.44H53.66V53.66h48.78v48.78Z"/><path fill="#F9AD00" d="M156.1 102.44h-48.78V53.66h48.78v48.78Z"/><path fill="#4E4E4E" d="M48.78 156.1H0v-48.78h48.78v48.78ZM102.44 156.1H53.66v-48.78h48.78v48.78ZM156.1 156.1h-48.78v-48.78h48.78v48.78Z"/></svg>}, - { title: "yarn", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256"><path fill="#368FB9" d="M128 0C57.328 0 0 57.328 0 128s57.328 128 128 128 128-57.328 128-128S198.672 0 128 0"/><path fill="#FFF" d="M203.317 174.06c-7.907 1.878-11.91 3.608-21.695 9.983-15.271 9.884-31.976 14.48-31.976 14.48s-1.383 2.076-5.387 3.015c-6.918 1.68-32.963 3.114-35.335 3.163-6.376.05-10.28-1.63-11.367-4.25-3.311-7.907 4.744-11.367 4.744-11.367s-1.779-1.087-2.817-2.076c-.939-.939-1.927-2.816-2.224-2.125-1.235 3.015-1.878 10.379-5.189 13.69-4.547 4.596-13.146 3.064-18.236.395-5.585-2.965.395-9.933.395-9.933s-3.015 1.779-5.436-1.878c-2.175-3.36-4.2-9.094-3.657-16.16.593-8.056 9.587-15.865 9.587-15.865s-1.581-11.91 3.608-24.117c4.695-11.12 17.347-20.065 17.347-20.065s-10.626-11.762-6.672-22.338c2.57-6.92 3.608-6.87 4.448-7.166 2.965-1.137 5.831-2.373 7.957-4.695 10.625-11.466 24.166-9.292 24.166-9.292s6.425-19.52 12.356-15.715c1.828 1.186 8.401 15.814 8.401 15.814s7.018-4.102 7.809-2.57c4.25 8.254 4.744 24.019 2.866 33.607-3.163 15.814-11.07 24.315-14.233 29.652-.741 1.236 8.5 5.14 14.332 21.3 5.387 14.777.593 27.182 1.433 28.566.148.247.198.346.198.346s6.177.494 18.582-7.166c6.622-4.102 14.48-8.698 23.425-8.797 8.65-.149 9.094 9.983 2.57 11.564zm11.763-7.265c-.89-7.017-6.82-11.86-14.431-11.762-11.367.148-20.905 6.03-27.231 9.934-2.471 1.532-4.596 2.669-6.425 3.509.395-5.733.05-13.245-2.916-21.498-3.608-9.885-8.45-15.963-11.91-19.472 4.003-5.832 9.489-14.332 12.058-27.478 2.224-11.219 1.533-28.664-3.558-38.45-1.038-1.976-2.767-3.41-4.942-4.003-.89-.247-2.57-.741-5.881.198-4.991-10.329-6.721-11.416-8.056-12.306-2.767-1.779-6.029-2.174-9.093-1.038-4.102 1.483-7.61 5.437-10.922 12.454a51.47 51.47 0 0 0-1.334 3.015c-6.277.445-16.161 2.718-24.513 11.762-1.038 1.137-3.064 1.977-5.19 2.768h.05c-4.349 1.532-6.326 5.09-8.747 11.515-3.361 8.994.098 17.84 3.508 23.574-4.645 4.151-10.823 10.773-14.084 18.532-4.053 9.588-4.498 18.978-4.35 24.068-3.459 3.658-8.796 10.527-9.39 18.237-.79 10.773 3.114 18.088 4.844 20.756.494.791 1.038 1.434 1.63 2.076-.197 1.334-.246 2.768.05 4.25.643 3.46 2.817 6.277 6.128 8.056 6.524 3.46 15.617 4.942 22.635 1.433 2.52 2.669 7.117 5.239 15.469 5.239h.494c2.125 0 29.109-1.433 36.967-3.36 3.509-.841 5.93-2.324 7.512-3.658 5.04-1.582 18.977-6.326 32.123-14.826 9.291-6.03 12.504-7.315 19.423-8.995 6.72-1.63 10.922-7.759 10.082-14.53z"/></svg> }, - { title: "npm", titleIcon: <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256"><path fill="#C12127" d="M0 256V0h256v256z"/><path fill="#FFF" d="M48 48h160v160h-32V80h-48v128H48z"/></svg> } -]; - ## Package manager Run the following command to install the tokens package. -<Tabs tabs={installMethods}> - <div> - ```shell - pnpm add @hopper-ui/tokens - ``` - </div> - <div> - ```shell - yarn add -D @hopper-ui/tokens - ``` - </div> - <div> - ```shell - npm add -D @hopper-ui/tokens - ``` - </div> -</Tabs> +<PackageInstallation library="tokens" mod="prod" /> diff --git a/apps/docs/datas/components/Button.json b/apps/docs/datas/components/Button.json new file mode 100644 index 000000000..9b7263605 --- /dev/null +++ b/apps/docs/datas/components/Button.json @@ -0,0 +1 @@ +[{"tags":{},"filePath":"/Users/franck.gaudin/Devel/DS/wl-hopper/packages/components/src/buttons/src/Button.tsx","description":"Buttons are used to initialize an action. Button labels express what action will occur when the user interacts with it.\n\n[View Documentation](TODO)","displayName":"Button","methods":[],"props":{"variant":{"defaultValue":{"value":"\"primary\""},"description":"The visual style of the button.\n*","name":"variant","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"\"primary\" | \"secondary\" | \"danger\" | \"upsell\" | \"ghost-primary\" | \"ghost-secondary\" | \"ghost-danger\""}},"size":{"defaultValue":{"value":"\"md\""},"description":"A button can vary in size.","name":"size","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"ResponsiveProp<\"sm\" | \"md\">"}},"fluid":{"defaultValue":null,"description":"Whether or not the button takes up the width of its container.","name":"fluid","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"ResponsiveProp<boolean>"}},"isLoading":{"defaultValue":null,"description":"","name":"isLoading","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"boolean"}},"href":{"defaultValue":null,"description":"A URL to link to. Setting this makes the component render an `a` tag instead of a `button`","name":"href","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"target":{"defaultValue":null,"description":"The target window for the link.","name":"target","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"rel":{"defaultValue":null,"description":"The relationship between the linked resource and the current page. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel).","name":"rel","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"form":{"defaultValue":null,"description":"The <form> element to associate the button with.\nThe value of this attribute must be the id of a <form> in the same document.","name":"form","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"slot":{"defaultValue":null,"description":"A slot name for the component. Slots allow the component to receive props from a parent component.\nAn explicit `null` value indicates that the local props completely override all props received from a parent.","name":"slot","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"SlotProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"SlotProps"}],"required":false,"type":{"name":"string"}},"style":{"defaultValue":null,"description":"The inline [style](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) for the element. A function may be provided to compute the style based on component state.","name":"style","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"StyleRenderProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"StyleRenderProps"}],"required":false,"type":{"name":"CSSProperties | ((values: ButtonRenderProps) => CSSProperties)"}},"children":{"defaultValue":null,"description":"The children of the component. A function may be provided to alter the children based on component state.","name":"children","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"RenderProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"RenderProps"}],"required":false,"type":{"name":"ReactNode | ((values: ButtonRenderProps) => ReactNode)"}},"isDisabled":{"defaultValue":null,"description":"Whether the button is disabled.","name":"isDisabled","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"boolean"}},"onPress":{"defaultValue":null,"description":"Handler that is called when the press is released over the target.","name":"onPress","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"}],"required":false,"type":{"name":"(e: PressEvent) => void"}},"onPressStart":{"defaultValue":null,"description":"Handler that is called when a press interaction starts.","name":"onPressStart","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"}],"required":false,"type":{"name":"(e: PressEvent) => void"}},"onPressEnd":{"defaultValue":null,"description":"Handler that is called when a press interaction ends, either\nover the target or when the pointer leaves the target.","name":"onPressEnd","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"}],"required":false,"type":{"name":"(e: PressEvent) => void"}},"onPressChange":{"defaultValue":null,"description":"Handler that is called when the press state changes.","name":"onPressChange","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"}],"required":false,"type":{"name":"(isPressed: boolean) => void"}},"onPressUp":{"defaultValue":null,"description":"Handler that is called when a press is released over the target, regardless of\nwhether it started on the target or not.","name":"onPressUp","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"}],"required":false,"type":{"name":"(e: PressEvent) => void"}},"autoFocus":{"defaultValue":null,"description":"Whether the element should receive focus on render.","name":"autoFocus","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusableProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusableProps"}],"required":false,"type":{"name":"boolean"}},"onFocus":{"defaultValue":null,"description":"Handler that is called when the element receives focus.","name":"onFocus","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"}],"required":false,"type":{"name":"(e: FocusEvent<Element, Element>) => void"}},"onBlur":{"defaultValue":null,"description":"Handler that is called when the element loses focus.","name":"onBlur","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"}],"required":false,"type":{"name":"(e: FocusEvent<Element, Element>) => void"}},"onFocusChange":{"defaultValue":null,"description":"Handler that is called when the element's focus status changes.","name":"onFocusChange","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"}],"required":false,"type":{"name":"(isFocused: boolean) => void"}},"onKeyDown":{"defaultValue":null,"description":"Handler that is called when a key is pressed.","name":"onKeyDown","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"KeyboardEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"KeyboardEvents"}],"required":false,"type":{"name":"(e: KeyboardEvent) => void"}},"onKeyUp":{"defaultValue":null,"description":"Handler that is called when a key is released.","name":"onKeyUp","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"KeyboardEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"KeyboardEvents"}],"required":false,"type":{"name":"(e: KeyboardEvent) => void"}},"aria-expanded":{"defaultValue":null,"description":"Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed.","name":"aria-expanded","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"}],"required":false,"type":{"name":"boolean | \"true\" | \"false\""}},"aria-haspopup":{"defaultValue":null,"description":"Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element.","name":"aria-haspopup","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"}],"required":false,"type":{"name":"boolean | \"dialog\" | \"menu\" | \"grid\" | \"true\" | \"false\" | \"listbox\" | \"tree\""}},"aria-controls":{"defaultValue":null,"description":"Identifies the element (or elements) whose contents or presence are controlled by the current element.","name":"aria-controls","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"}],"required":false,"type":{"name":"string"}},"aria-pressed":{"defaultValue":null,"description":"Indicates the current \"pressed\" state of toggle buttons.","name":"aria-pressed","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"}],"required":false,"type":{"name":"boolean | \"true\" | \"false\" | \"mixed\""}},"type":{"defaultValue":{"value":"'button'"},"description":"The behavior of the button when used in an HTML form.","name":"type","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"}],"required":false,"type":{"name":"\"button\" | \"submit\" | \"reset\""}},"excludeFromTabOrder":{"defaultValue":null,"description":"Whether to exclude the element from the sequential tab order. If true,\nthe element will not be focusable via the keyboard by tabbing. This should\nbe avoided except in rare scenarios where an alternative means of accessing\nthe element or its functionality via the keyboard is available.","name":"excludeFromTabOrder","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"FocusableDOMProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"FocusableDOMProps"}],"required":false,"type":{"name":"boolean"}},"id":{"defaultValue":null,"description":"The element's unique identifier. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id).","name":"id","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"DOMProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"DOMProps"}],"required":false,"type":{"name":"string"}},"aria-label":{"defaultValue":null,"description":"Defines a string value that labels the current element.","name":"aria-label","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"}],"required":false,"type":{"name":"string"}},"aria-labelledby":{"defaultValue":null,"description":"Identifies the element (or elements) that labels the current element.","name":"aria-labelledby","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"}],"required":false,"type":{"name":"string"}},"aria-describedby":{"defaultValue":null,"description":"Identifies the element (or elements) that describes the object.","name":"aria-describedby","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"}],"required":false,"type":{"name":"string"}},"aria-details":{"defaultValue":null,"description":"Identifies the element (or elements) that provide a detailed, extended description for the object.","name":"aria-details","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"}],"required":false,"type":{"name":"string"}},"formAction":{"defaultValue":null,"description":"The URL that processes the information submitted by the button.\nOverrides the action attribute of the button's form owner.","name":"formAction","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"formEncType":{"defaultValue":null,"description":"Indicates how to encode the form data that is submitted.","name":"formEncType","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"formMethod":{"defaultValue":null,"description":"Indicates the HTTP method used to submit the form.","name":"formMethod","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"formNoValidate":{"defaultValue":null,"description":"Indicates that the form is not to be validated when it is submitted.","name":"formNoValidate","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"boolean"}},"formTarget":{"defaultValue":null,"description":"Overrides the target attribute of the button's form owner.","name":"formTarget","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"value":{"defaultValue":null,"description":"The value associated with the button's name when it's submitted with the form data.","name":"value","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"onHoverStart":{"defaultValue":null,"description":"Handler that is called when a hover interaction starts.","name":"onHoverStart","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"}],"required":false,"type":{"name":"(e: HoverEvent) => void"}},"onHoverEnd":{"defaultValue":null,"description":"Handler that is called when a hover interaction ends.","name":"onHoverEnd","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"}],"required":false,"type":{"name":"(e: HoverEvent) => void"}},"onHoverChange":{"defaultValue":null,"description":"Handler that is called when the hover state changes.","name":"onHoverChange","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"}],"required":false,"type":{"name":"(isHovering: boolean) => void"}},"className":{"defaultValue":null,"description":"The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the element. A function may be provided to compute the class based on component state.","name":"className","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"StyleRenderProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"StyleRenderProps"}],"required":false,"type":{"name":"string | ((values: ButtonRenderProps) => string)"}},"name":{"defaultValue":null,"description":"Submitted as a pair with the button's value as part of the form data.","name":"name","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"ref":{"defaultValue":null,"description":"Allows getting a ref to the component instance.\nOnce the component unmounts, React will set `ref.current` to `null`\n(or call the ref with `null` if you passed a callback ref).\n@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}","name":"ref","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@types+react@18.2.67/node_modules/@types/react/index.d.ts","name":"RefAttributes"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@types+react@18.2.67/node_modules/@types/react/index.d.ts","name":"RefAttributes"}],"required":false,"type":{"name":"LegacyRef<HTMLElement>"}},"key":{"defaultValue":null,"description":"","name":"key","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@types+react@18.2.67/node_modules/@types/react/index.d.ts","name":"Attributes"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@types+react@18.2.67/node_modules/@types/react/index.d.ts","name":"Attributes"}],"required":false,"type":{"name":"Key"}}},"groups":{"default":{"variant":{"defaultValue":{"value":"\"primary\""},"description":"The visual style of the button.\n*","name":"variant","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"\"primary\" | \"secondary\" | \"danger\" | \"upsell\" | \"ghost-primary\" | \"ghost-secondary\" | \"ghost-danger\""}},"size":{"defaultValue":{"value":"\"md\""},"description":"A button can vary in size.","name":"size","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"ResponsiveProp<\"sm\" | \"md\">"}},"fluid":{"defaultValue":null,"description":"Whether or not the button takes up the width of its container.","name":"fluid","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"ResponsiveProp<boolean>"}},"isLoading":{"defaultValue":null,"description":"","name":"isLoading","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"boolean"}},"href":{"defaultValue":null,"description":"A URL to link to. Setting this makes the component render an `a` tag instead of a `button`","name":"href","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"target":{"defaultValue":null,"description":"The target window for the link.","name":"target","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"rel":{"defaultValue":null,"description":"The relationship between the linked resource and the current page. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel).","name":"rel","parent":{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/packages/components/src/buttons/src/Button.tsx","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"form":{"defaultValue":null,"description":"The <form> element to associate the button with.\nThe value of this attribute must be the id of a <form> in the same document.","name":"form","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"slot":{"defaultValue":null,"description":"A slot name for the component. Slots allow the component to receive props from a parent component.\nAn explicit `null` value indicates that the local props completely override all props received from a parent.","name":"slot","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"SlotProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"SlotProps"}],"required":false,"type":{"name":"string"}},"style":{"defaultValue":null,"description":"The inline [style](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) for the element. A function may be provided to compute the style based on component state.","name":"style","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"StyleRenderProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"StyleRenderProps"}],"required":false,"type":{"name":"CSSProperties | ((values: ButtonRenderProps) => CSSProperties)"}},"children":{"defaultValue":null,"description":"The children of the component. A function may be provided to alter the children based on component state.","name":"children","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"RenderProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"RenderProps"}],"required":false,"type":{"name":"ReactNode | ((values: ButtonRenderProps) => ReactNode)"}},"isDisabled":{"defaultValue":null,"description":"Whether the button is disabled.","name":"isDisabled","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"boolean"}},"autoFocus":{"defaultValue":null,"description":"Whether the element should receive focus on render.","name":"autoFocus","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusableProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusableProps"}],"required":false,"type":{"name":"boolean"}},"excludeFromTabOrder":{"defaultValue":null,"description":"Whether to exclude the element from the sequential tab order. If true,\nthe element will not be focusable via the keyboard by tabbing. This should\nbe avoided except in rare scenarios where an alternative means of accessing\nthe element or its functionality via the keyboard is available.","name":"excludeFromTabOrder","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"FocusableDOMProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"FocusableDOMProps"}],"required":false,"type":{"name":"boolean"}},"id":{"defaultValue":null,"description":"The element's unique identifier. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id).","name":"id","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"DOMProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"DOMProps"}],"required":false,"type":{"name":"string"}},"formAction":{"defaultValue":null,"description":"The URL that processes the information submitted by the button.\nOverrides the action attribute of the button's form owner.","name":"formAction","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"formEncType":{"defaultValue":null,"description":"Indicates how to encode the form data that is submitted.","name":"formEncType","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"formMethod":{"defaultValue":null,"description":"Indicates the HTTP method used to submit the form.","name":"formMethod","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"formNoValidate":{"defaultValue":null,"description":"Indicates that the form is not to be validated when it is submitted.","name":"formNoValidate","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"boolean"}},"formTarget":{"defaultValue":null,"description":"Overrides the target attribute of the button's form owner.","name":"formTarget","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"value":{"defaultValue":null,"description":"The value associated with the button's name when it's submitted with the form data.","name":"value","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"className":{"defaultValue":null,"description":"The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the element. A function may be provided to compute the class based on component state.","name":"className","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"StyleRenderProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"StyleRenderProps"}],"required":false,"type":{"name":"string | ((values: ButtonRenderProps) => string)"}},"name":{"defaultValue":null,"description":"Submitted as a pair with the button's value as part of the form data.","name":"name","parent":{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/react-aria-components@1.1.1_react-dom@18.2.0_react@18.2.0/node_modules/react-aria-components/dist/types.d.ts","name":"ButtonProps"}],"required":false,"type":{"name":"string"}},"ref":{"defaultValue":null,"description":"Allows getting a ref to the component instance.\nOnce the component unmounts, React will set `ref.current` to `null`\n(or call the ref with `null` if you passed a callback ref).\n@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}","name":"ref","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@types+react@18.2.67/node_modules/@types/react/index.d.ts","name":"RefAttributes"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@types+react@18.2.67/node_modules/@types/react/index.d.ts","name":"RefAttributes"}],"required":false,"type":{"name":"LegacyRef<HTMLElement>"}},"key":{"defaultValue":null,"description":"","name":"key","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@types+react@18.2.67/node_modules/@types/react/index.d.ts","name":"Attributes"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@types+react@18.2.67/node_modules/@types/react/index.d.ts","name":"Attributes"}],"required":false,"type":{"name":"Key"}}},"events":{"onPress":{"defaultValue":null,"description":"Handler that is called when the press is released over the target.","name":"onPress","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"}],"required":false,"type":{"name":"(e: PressEvent) => void"}},"onPressStart":{"defaultValue":null,"description":"Handler that is called when a press interaction starts.","name":"onPressStart","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"}],"required":false,"type":{"name":"(e: PressEvent) => void"}},"onPressEnd":{"defaultValue":null,"description":"Handler that is called when a press interaction ends, either\nover the target or when the pointer leaves the target.","name":"onPressEnd","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"}],"required":false,"type":{"name":"(e: PressEvent) => void"}},"onPressChange":{"defaultValue":null,"description":"Handler that is called when the press state changes.","name":"onPressChange","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"}],"required":false,"type":{"name":"(isPressed: boolean) => void"}},"onPressUp":{"defaultValue":null,"description":"Handler that is called when a press is released over the target, regardless of\nwhether it started on the target or not.","name":"onPressUp","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"PressEvents"}],"required":false,"type":{"name":"(e: PressEvent) => void"}},"onFocus":{"defaultValue":null,"description":"Handler that is called when the element receives focus.","name":"onFocus","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"}],"required":false,"type":{"name":"(e: FocusEvent<Element, Element>) => void"}},"onBlur":{"defaultValue":null,"description":"Handler that is called when the element loses focus.","name":"onBlur","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"}],"required":false,"type":{"name":"(e: FocusEvent<Element, Element>) => void"}},"onFocusChange":{"defaultValue":null,"description":"Handler that is called when the element's focus status changes.","name":"onFocusChange","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"FocusEvents"}],"required":false,"type":{"name":"(isFocused: boolean) => void"}},"onKeyDown":{"defaultValue":null,"description":"Handler that is called when a key is pressed.","name":"onKeyDown","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"KeyboardEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"KeyboardEvents"}],"required":false,"type":{"name":"(e: KeyboardEvent) => void"}},"onKeyUp":{"defaultValue":null,"description":"Handler that is called when a key is released.","name":"onKeyUp","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"KeyboardEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"KeyboardEvents"}],"required":false,"type":{"name":"(e: KeyboardEvent) => void"}},"onHoverStart":{"defaultValue":null,"description":"Handler that is called when a hover interaction starts.","name":"onHoverStart","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"}],"required":false,"type":{"name":"(e: HoverEvent) => void"}},"onHoverEnd":{"defaultValue":null,"description":"Handler that is called when a hover interaction ends.","name":"onHoverEnd","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"}],"required":false,"type":{"name":"(e: HoverEvent) => void"}},"onHoverChange":{"defaultValue":null,"description":"Handler that is called when the hover state changes.","name":"onHoverChange","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/events.d.ts","name":"HoverEvents"}],"required":false,"type":{"name":"(isHovering: boolean) => void"}}},"a11y":{"aria-expanded":{"defaultValue":null,"description":"Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed.","name":"aria-expanded","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"}],"required":false,"type":{"name":"boolean | \"true\" | \"false\""}},"aria-haspopup":{"defaultValue":null,"description":"Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element.","name":"aria-haspopup","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"}],"required":false,"type":{"name":"boolean | \"dialog\" | \"menu\" | \"grid\" | \"true\" | \"false\" | \"listbox\" | \"tree\""}},"aria-controls":{"defaultValue":null,"description":"Identifies the element (or elements) whose contents or presence are controlled by the current element.","name":"aria-controls","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"}],"required":false,"type":{"name":"string"}},"aria-pressed":{"defaultValue":null,"description":"Indicates the current \"pressed\" state of toggle buttons.","name":"aria-pressed","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"}],"required":false,"type":{"name":"boolean | \"true\" | \"false\" | \"mixed\""}},"type":{"defaultValue":{"value":"'button'"},"description":"The behavior of the button when used in an HTML form.","name":"type","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+button@3.9.2_react@18.2.0/node_modules/@react-types/button/src/index.d.ts","name":"AriaBaseButtonProps"}],"required":false,"type":{"name":"\"button\" | \"submit\" | \"reset\""}},"aria-label":{"defaultValue":null,"description":"Defines a string value that labels the current element.","name":"aria-label","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"}],"required":false,"type":{"name":"string"}},"aria-labelledby":{"defaultValue":null,"description":"Identifies the element (or elements) that labels the current element.","name":"aria-labelledby","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"}],"required":false,"type":{"name":"string"}},"aria-describedby":{"defaultValue":null,"description":"Identifies the element (or elements) that describes the object.","name":"aria-describedby","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"}],"required":false,"type":{"name":"string"}},"aria-details":{"defaultValue":null,"description":"Identifies the element (or elements) that provide a detailed, extended description for the object.","name":"aria-details","parent":{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"},"declarations":[{"fileName":"wl-hopper/node_modules/.pnpm/@react-types+shared@3.22.1_react@18.2.0/node_modules/@react-types/shared/src/dom.d.ts","name":"AriaLabelingProps"}],"required":false,"type":{"name":"string"}}}}}] \ No newline at end of file diff --git a/apps/docs/package.json b/apps/docs/package.json index 1fee259c0..2de47632f 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -11,7 +11,8 @@ "lint": "next lint", "lint:types": "tsc --noEmit", "storybook": "storybook dev -p 6010", - "build:storybook": "storybook build" + "build:storybook": "storybook build", + "build:componentData": "tsx scripts/generateComponentData.mts" }, "dependencies": { "clsx": "2.1.0", @@ -32,6 +33,7 @@ "devDependencies": { "@codesandbox/sandpack-react": "^2.13.5", "@hopper-ui/components": "workspace:*", + "@hopper-ui/icons": "workspace:*", "@hopper-ui/tokens": "workspace:*", "@storybook/addon-essentials": "8.0.2", "@storybook/addon-interactions": "8.0.2", @@ -47,6 +49,8 @@ "eslint": "8.57.0", "eslint-config-next": "14.1.4", "eslint-plugin-storybook": "0.8.0", + "react-docgen-typescript": "^2.2.2", + "shiki": "^1.3.0", "storybook": "8.0.2", "tsconfig-paths-webpack-plugin": "4.1.0", "typescript": "5.4.2" diff --git a/apps/docs/scripts/generateComponentData.mts b/apps/docs/scripts/generateComponentData.mts new file mode 100644 index 000000000..0339aff7d --- /dev/null +++ b/apps/docs/scripts/generateComponentData.mts @@ -0,0 +1,146 @@ +import fs from "fs"; +import path from "path"; +import docgenTs, {type ComponentDoc, PropItem} from "react-docgen-typescript"; + +interface ComponentData { + name: string; + filePath: string; +} + +interface Group { + [key: string]: PropItem; +} + +type Groups = { [key: string]: Group } + +type GroupsConfig = { + [key: string]: string; +} + +export interface ComponentDocWithGroups extends ComponentDoc { + groups: Groups; +} + +const PACKAGES = path.join(process.cwd(), "..", "..", "packages", "components", "src"); +const COMPONENT_DATA = path.join(process.cwd(), "datas", "components"); + +const tsConfigParser = docgenTs.withDefaultConfig({ + propFilter: (prop) => { + // Remove props from StyledSystemProps + return prop?.parent?.name !== "StyledSystemProps"; + } +}); + +async function writeFile(filename: string, data: ComponentDocWithGroups[]) { + if (!fs.existsSync(COMPONENT_DATA)) { + fs.mkdirSync(COMPONENT_DATA) + } + + fs.writeFile(`${COMPONENT_DATA}/${filename}.json`, JSON.stringify(data), function (err) { + if (err) { + console.error(err) + throw err; + } + console.log(`${filename} api is created!`) + }) +} + +function getComponentName(filePath: string) { + return path.basename(filePath, path.extname(filePath)); +} + +function getFormattedData(data: ComponentDoc[]): ComponentDocWithGroups[] { + // Define the groups and their corresponding terms + + const groupsConfig: GroupsConfig = { + events: "Events", + a11y: 'Aria', + // Add more groups here as needed + }; + + return data.map(component => { + // Initialize the groups + const groups: Groups = { + default: {}, + ...Object.keys(groupsConfig).reduce((acc, group) => ({...acc, [group]: {}}), {}), + }; + + Object.entries(component.props).forEach(([key, prop]) => { + let added = false; + + // Check each group to see if the prop should be added to it + Object.entries(groupsConfig).forEach(([group, term]) => { + if (prop.parent?.name.includes(term)) { + groups[group][key] = prop; + added = true; + } + }); + + // If the prop wasn't added to any group, add it to the default group + if (!added) { + groups.default[key] = prop; + } + }); + + return { + ...component, + groups + }; + }) +} + +async function generateComponentList(source: string): Promise<(ComponentData | undefined)[]> { + const subdirs = fs.readdirSync(source); + const files = await Promise.all(subdirs.map(async (subdir) => { + const res = path.resolve(source, subdir); + + // Checks if the path corresponds to a directory + if (fs.statSync(res).isDirectory()) { + return generateComponentList(res); + } + + // Checks whether the file is in the docs or tests directory + if (/\/(docs|tests)\/|index\.ts$/.test(res)) { + return; + } + + // Checks whether the file is a .ts or .tsx file + if (/\.tsx?$/.test(res)) { + const name = getComponentName(res); + return {name, filePath: res}; + } + })); + + return files.flat().filter(Boolean) as ComponentData[] +} + +async function generateComponentData() { + console.log('Start api generation for components'); + + // const components = await generateComponentList(PACKAGES); + // Data for the tests only + const components = [{ + name: "Button", + filePath: `${PACKAGES}/buttons/src/Button.tsx` + }] + + if (!components.length) { + console.error('No components found'); + return; + } + + for (const component of components) { + if (component) { + + const data = tsConfigParser.parse(component.filePath); + const {name} = component; + const formattedData = getFormattedData(data); + + await writeFile(name, formattedData); + } + } + + return; +} + +generateComponentData().then(() => console.log('🎉 Success')).catch(err => console.error(err)); diff --git a/packages/components/src/buttons/src/Button.tsx b/packages/components/src/buttons/src/Button.tsx index 356cfcfcd..4329e1a0f 100644 --- a/packages/components/src/buttons/src/Button.tsx +++ b/packages/components/src/buttons/src/Button.tsx @@ -1,15 +1,33 @@ import { IconContext } from "@hopper-ui/icons"; -import { type StyledComponentProps, useStyledSystem, type ResponsiveProp, useResponsiveValue } from "@hopper-ui/styled-system"; +import { + type StyledComponentProps, + useStyledSystem, + type ResponsiveProp, + useResponsiveValue +} from "@hopper-ui/styled-system"; import { useRouter, shouldClientNavigate, filterDOMProps, chain } from "@react-aria/utils"; import { type ForwardedRef, forwardRef, type MouseEvent, type MutableRefObject } from "react"; import { useButton, useHover, useFocusRing, mergeProps } from "react-aria"; -import { useContextProps, composeRenderProps, type ButtonProps as RACButtonProps, type ButtonRenderProps, ButtonContext as RACButtonContext } from "react-aria-components"; +import { + useContextProps, + composeRenderProps, + type ButtonProps as RACButtonProps, + type ButtonRenderProps, + ButtonContext as RACButtonContext +} from "react-aria-components"; import { IconListContext } from "../../IconList/index.ts"; import { useLocalizedString } from "../../intl/index.ts"; import { Spinner } from "../../Spinner/index.ts"; import { TextContext, Text } from "../../Text/index.ts"; -import { composeClassnameRenderProps, SlotProvider, cssModule, useSlot, isTextOnlyChildren, useRenderProps } from "../../utils/index.ts"; +import { + composeClassnameRenderProps, + SlotProvider, + cssModule, + useSlot, + isTextOnlyChildren, + useRenderProps +} from "../../utils/index.ts"; import { ButtonContext, type ButtonContextValue } from "./ButtonContext.ts"; @@ -72,7 +90,13 @@ function useSimulatedRACButton(props: ButtonProps, ref: MutableRefObject<HTMLEle isDisabled: props.isDisabled || props.isLoading }, ref); - const state: ButtonRenderProps = { isFocused, isFocusVisible, isHovered, isPressed, isDisabled: props.isDisabled || false }; + const state: ButtonRenderProps = { + isFocused, + isFocusVisible, + isHovered, + isPressed, + isDisabled: props.isDisabled || false + }; const mergedProps = { ...mergeProps(buttonProps, focusProps, hoverProps), diff --git a/packages/icons/CHANGELOG.md b/packages/icons/CHANGELOG.md index f2401aaa2..4b108ad37 100644 --- a/packages/icons/CHANGELOG.md +++ b/packages/icons/CHANGELOG.md @@ -1,5 +1,11 @@ # @hopper-ui/icons +## 1.10.1 + +### Patch Changes + +- d78aefb: Fix an issue preventing pointer events on icons + ## 1.10.0 ### Minor Changes diff --git a/packages/icons/package.json b/packages/icons/package.json index 9843f46a0..3490b5c03 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -1,7 +1,7 @@ { "name": "@hopper-ui/icons", "author": "Workleap", - "version": "1.10.0", + "version": "1.10.1", "description": "The icons package.", "license": "Apache-2.0", "repository": { diff --git a/packages/icons/src/Icon.module.css b/packages/icons/src/Icon.module.css index f1a66a304..b4fd98331 100644 --- a/packages/icons/src/Icon.module.css +++ b/packages/icons/src/Icon.module.css @@ -1,10 +1,6 @@ .hop-Icon { - pointer-events: none; - display: inline-block; flex-shrink: 0; - color: inherit; - fill: currentcolor; } diff --git a/packages/icons/src/RichIcon.module.css b/packages/icons/src/RichIcon.module.css index e67fdfc3b..af3729983 100644 --- a/packages/icons/src/RichIcon.module.css +++ b/packages/icons/src/RichIcon.module.css @@ -4,7 +4,6 @@ --hop-richicon-placeholder-icon-color: var(--hop-decorative-option7-icon); --hop-richicon-placeholder-icon-strong-color: var(--hop-samoyed); - pointer-events: none; display: inline-block; flex-shrink: 0; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ee78d2333..870b8dea7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -183,6 +183,9 @@ importers: '@hopper-ui/components': specifier: workspace:* version: link:../../packages/components + '@hopper-ui/icons': + specifier: workspace:* + version: link:../../packages/icons '@hopper-ui/tokens': specifier: workspace:* version: link:../../packages/tokens @@ -228,6 +231,12 @@ importers: eslint-plugin-storybook: specifier: 0.8.0 version: 0.8.0(eslint@8.57.0)(typescript@5.4.2) + react-docgen-typescript: + specifier: ^2.2.2 + version: 2.2.2(typescript@5.4.2) + shiki: + specifier: ^1.3.0 + version: 1.3.0 storybook: specifier: 8.0.2 version: 8.0.2(react-dom@18.2.0)(react@18.2.0) @@ -242,7 +251,7 @@ importers: dependencies: '@hopper-ui/icons': specifier: '*' - version: 1.10.0(@hopper-ui/styled-system@packages+styled-system)(react-aria-components@1.1.1)(react-dom@18.2.0)(react@18.2.0) + version: link:../icons '@react-aria/utils': specifier: ^3.23.2 version: 3.23.2(react@18.2.0) @@ -2423,10 +2432,6 @@ packages: peerDependencies: '@effect-ts/otel-node': '*' peerDependenciesMeta: - '@effect-ts/core': - optional: true - '@effect-ts/otel': - optional: true '@effect-ts/otel-node': optional: true dependencies: @@ -3075,22 +3080,6 @@ packages: '@hapi/hoek': 9.3.0 dev: true - /@hopper-ui/icons@1.10.0(@hopper-ui/styled-system@packages+styled-system)(react-aria-components@1.1.1)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-B4XCmADS1Wc4DiZTTs2PzD4tXl5kgyCwc4Urw9dcOcxO48Twf97whVlj0VGprQ90uKXEC1pCk0Kcgi1jA0ekkA==} - peerDependencies: - '@hopper-ui/styled-system': ^1 - react: ^18 - react-aria-components: ^1.1.0 - react-dom: ^18 - dependencies: - '@hopper-ui/styled-system': link:packages/styled-system - '@react-aria/utils': 3.23.2(react@18.2.0) - clsx: 2.1.0 - react: 18.2.0 - react-aria-components: 1.1.1(react-dom@18.2.0)(react@18.2.0) - react-dom: 18.2.0(react@18.2.0) - dev: false - /@humanwhocodes/config-array@0.11.14: resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -5800,7 +5789,6 @@ packages: /@shikijs/core@1.3.0: resolution: {integrity: sha512-7fedsBfuILDTBmrYZNFI8B6ATTxhQAasUHllHmjvSZPnoq4bULWoTpHwmuQvZ8Aq03/tAa2IGo6RXqWtHdWaCA==} - dev: false /@sideway/address@4.1.5: resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} @@ -18728,7 +18716,6 @@ packages: resolution: {integrity: sha512-9aNdQy/etMXctnPzsje1h1XIGm9YfRcSksKOGqZWXA/qP9G18/8fpz5Bjpma8bOgz3tqIpjERAd6/lLjFyzoww==} dependencies: '@shikijs/core': 1.3.0 - dev: false /side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}