-
Notifications
You must be signed in to change notification settings - Fork 0
Refine component consistency and story tests #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
lifeiscontent
wants to merge
14
commits into
main
Choose a base branch
from
component-consistency-pass
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
e731a0e
Refine component slot and story consistency
lifeiscontent 9508882
Expand Storybook coverage for component states
lifeiscontent ee2bf17
Derive component axes from VariantProps
lifeiscontent e8fccca
Align NavItem render composition
lifeiscontent 8ba342b
Use Base UI primitives for button and nav disclosure
lifeiscontent a99c474
Refactor Base UI component boundaries
lifeiscontent 134e4d9
Split remaining component child files
lifeiscontent e46ad2f
Polish component boundaries and generic props
lifeiscontent c08e211
Improve Storybook coverage
lifeiscontent f5afc58
Refactor component composition and story coverage
lifeiscontent f18f929
Extend Tailwind shorthand lint fixes
lifeiscontent 3bd8684
Restructure propel into base / ui / components tiers
lifeiscontent 98de972
Upgrade vite-plus to 0.2.0
lifeiscontent a4ce5f4
Exclude agent worktrees from vitest discovery
lifeiscontent File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { BaseTextArea, type BaseTextAreaProps } from "./text-area"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import { Field as BaseField } from "@base-ui/react/field"; | ||
| import * as React from "react"; | ||
|
|
||
| type BaseFieldControlProps = React.ComponentProps<typeof BaseField.Control>; | ||
|
|
||
| type NativeTextAreaProps = Omit< | ||
| React.ComponentProps<"textarea">, | ||
| keyof BaseFieldControlProps | "children" | "className" | "style" | ||
| >; | ||
|
|
||
| export type BaseTextAreaProps = BaseFieldControlProps & | ||
| NativeTextAreaProps & { | ||
| /** The default value of the textarea. Use when uncontrolled. */ | ||
| defaultValue?: React.ComponentProps<"textarea">["defaultValue"]; | ||
| /** The value of the textarea. Use when controlled. */ | ||
| value?: React.ComponentProps<"textarea">["value"]; | ||
| }; | ||
|
|
||
| /** | ||
| * A native textarea element that automatically works with Field. Renders a `<textarea>` element. | ||
| * | ||
| * Adapted from Base UI Input. | ||
| */ | ||
| export const BaseTextArea = React.forwardRef<HTMLElement, BaseTextAreaProps>( | ||
| function BaseTextArea(props, forwardedRef) { | ||
| return <BaseField.Control ref={forwardedRef} render={<textarea />} {...props} />; | ||
| }, | ||
| ); | ||
|
|
||
| if (process.env.NODE_ENV !== "production") { | ||
| BaseTextArea.displayName = "BaseTextArea"; | ||
| } |
18 changes: 18 additions & 0 deletions
18
packages/propel/src/components/accordion/accordion-panel.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { | ||
| AccordionPanel as AccordionPanelRoot, | ||
| type AccordionPanelProps as AccordionPanelRootProps, | ||
| } from "../../ui/accordion"; | ||
|
|
||
| export type AccordionPanelProps = AccordionPanelRootProps; | ||
|
|
||
| /** | ||
| * The ready-made accordion panel: composes the atomic `AccordionPanel` and adds the inner padding | ||
| * wrapper so content is inset from the trigger's edges. | ||
| */ | ||
| export function AccordionPanel({ children, ...props }: AccordionPanelProps) { | ||
| return ( | ||
| <AccordionPanelRoot {...props}> | ||
| <div className="px-3 pb-3">{children}</div> | ||
| </AccordionPanelRoot> | ||
| ); | ||
| } |
37 changes: 37 additions & 0 deletions
37
packages/propel/src/components/accordion/accordion-trigger.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import { ChevronDown } from "lucide-react"; | ||
| import type * as React from "react"; | ||
|
|
||
| import { NodeSlot } from "../../internal/node-slot"; | ||
| import { | ||
| AccordionTrigger as AccordionTriggerRoot, | ||
| type AccordionTriggerProps as AccordionTriggerRootProps, | ||
| } from "../../ui/accordion"; | ||
|
|
||
| export type AccordionTriggerProps = AccordionTriggerRootProps & { | ||
| /** | ||
| * Node rendered before the label (inline-start), matching the Figma header icon. Sized to the | ||
| * trigger's `--node-size`. Decorative, kept out of the name. | ||
| */ | ||
| inlineStartNode?: React.ReactNode; | ||
| }; | ||
|
|
||
| /** | ||
| * The ready-made accordion trigger: composes the atomic `AccordionTrigger` and lays out an optional | ||
| * `inlineStartNode`, the label, and the chevron that rotates when the panel opens. | ||
| */ | ||
| export function AccordionTrigger({ inlineStartNode, children, ...props }: AccordionTriggerProps) { | ||
| return ( | ||
| <AccordionTriggerRoot {...props}> | ||
| {inlineStartNode ? ( | ||
| <NodeSlot aria-hidden className="text-icon-secondary"> | ||
| {inlineStartNode} | ||
| </NodeSlot> | ||
| ) : null} | ||
| <span className="flex-1">{children}</span> | ||
| <ChevronDown | ||
| aria-hidden | ||
| className="size-3.5 shrink-0 text-icon-secondary transition-transform duration-200 group-data-panel-open:rotate-180" | ||
| /> | ||
| </AccordionTriggerRoot> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,105 +1,11 @@ | ||
| import { Accordion as BaseAccordion } from "@base-ui/react/accordion"; | ||
| import { cx } from "class-variance-authority"; | ||
| import { ChevronDown } from "lucide-react"; | ||
| import type * as React from "react"; | ||
|
|
||
| // Accordion is a structural component: the Figma "Accordion" spec only defines the | ||
| // collapsed/hover/expanded states (which Base UI drives as state, not props) — so | ||
| // there are no styling axes (variant/tone/magnitude) to expose. The header row uses | ||
| // `border/subtle` divider, `spacing/3` padding, `spacing/2` gap, `text/14` | ||
| // medium `text/primary` label, a `background/layer/transparent` surface that goes to | ||
| // `background/layer/transparent-hover` on hover, and an `icon/placeholder` chevron. | ||
|
|
||
| export type AccordionProps = Omit< | ||
| React.ComponentProps<typeof BaseAccordion.Root>, | ||
| "className" | "render" | "style" | ||
| >; | ||
|
|
||
| /** | ||
| * Groups a set of `AccordionItem`s. Single-open by default; pass `multiple` to allow several panels | ||
| * open at once. Use `defaultValue` (uncontrolled) or `value` + `onValueChange` (controlled) to | ||
| * drive which items are expanded. | ||
| */ | ||
| export function Accordion(props: AccordionProps) { | ||
| return <BaseAccordion.Root className="flex w-full flex-col" {...props} />; | ||
| } | ||
|
|
||
| export type AccordionItemProps = Omit< | ||
| React.ComponentProps<typeof BaseAccordion.Item>, | ||
| "className" | "render" | "style" | ||
| >; | ||
|
|
||
| /** A single collapsible section: pairs an `AccordionTrigger` with an `AccordionPanel`. */ | ||
| export function AccordionItem(props: AccordionItemProps) { | ||
| return <BaseAccordion.Item className="border-b border-subtle" {...props} />; | ||
| } | ||
|
|
||
| export type AccordionTriggerProps = Omit< | ||
| React.ComponentProps<typeof BaseAccordion.Trigger>, | ||
| "className" | "render" | "style" | ||
| > & { | ||
| /** | ||
| * Optional icon shown before the label, matching the Figma header icon. Named `leadingIcon` (not | ||
| * `icon`) to match Button/Input, so a `trailingIcon` can be added later without a breaking | ||
| * rename. | ||
| */ | ||
| leadingIcon?: React.ReactNode; | ||
| }; | ||
|
|
||
| /** | ||
| * The clickable header that opens and closes its panel. Renders an optional `leadingIcon`, the | ||
| * label, and a chevron that rotates when the panel is open. Base UI sets `aria-expanded` and | ||
| * `aria-controls` for you. | ||
| */ | ||
| export function AccordionTrigger({ leadingIcon, children, ...props }: AccordionTriggerProps) { | ||
| return ( | ||
| <BaseAccordion.Header className="flex"> | ||
| <BaseAccordion.Trigger | ||
| className={cx( | ||
| "group flex flex-1 items-center gap-2 p-3 text-start", | ||
| "text-14 font-medium text-primary", | ||
| "bg-layer-transparent hover:bg-layer-transparent-hover", | ||
| "cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-accent-strong", | ||
| "disabled:cursor-not-allowed disabled:opacity-60", | ||
| )} | ||
| {...props} | ||
| > | ||
| {leadingIcon ? ( | ||
| <span className="flex size-4 shrink-0 items-center justify-center text-icon-secondary"> | ||
| {leadingIcon} | ||
| </span> | ||
| ) : null} | ||
| <span className="flex-1">{children}</span> | ||
| <ChevronDown | ||
| aria-hidden | ||
| className="size-3.5 shrink-0 text-icon-secondary transition-transform duration-200 group-data-panel-open:rotate-180" | ||
| /> | ||
| </BaseAccordion.Trigger> | ||
| </BaseAccordion.Header> | ||
| ); | ||
| } | ||
|
|
||
| export type AccordionPanelProps = Omit< | ||
| React.ComponentProps<typeof BaseAccordion.Panel>, | ||
| "className" | "render" | "style" | ||
| >; | ||
|
|
||
| /** | ||
| * The collapsible content region for an item. Animates open/closed using Base UI's | ||
| * `--accordion-panel-height` so the height transitions smoothly. | ||
| */ | ||
| export function AccordionPanel({ children, ...props }: AccordionPanelProps) { | ||
| return ( | ||
| <BaseAccordion.Panel | ||
| className={cx( | ||
| "h-(--accordion-panel-height) overflow-hidden", | ||
| "text-14 text-secondary", | ||
| "transition-[height] duration-200 ease-out", | ||
| "data-ending-style:h-0 data-starting-style:h-0", | ||
| )} | ||
| {...props} | ||
| > | ||
| <div className="px-3 pb-3">{children}</div> | ||
| </BaseAccordion.Panel> | ||
| ); | ||
| } | ||
| export { AccordionPanel, type AccordionPanelProps } from "./accordion-panel"; | ||
| export { AccordionTrigger, type AccordionTriggerProps } from "./accordion-trigger"; | ||
| // Re-export the atomic structural parts so a full accordion is importable from this convenience. | ||
| export { | ||
| Accordion, | ||
| AccordionHeader, | ||
| type AccordionHeaderProps, | ||
| AccordionItem, | ||
| type AccordionItemProps, | ||
| type AccordionProps, | ||
| } from "../../ui/accordion"; |
24 changes: 24 additions & 0 deletions
24
packages/propel/src/components/alert-dialog/alert-dialog-content.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| import { | ||
| AlertDialogBackdrop, | ||
| AlertDialogPopup, | ||
| type AlertDialogPopupProps, | ||
| AlertDialogPortal, | ||
| AlertDialogViewport, | ||
| } from "../../ui/alert-dialog"; | ||
|
|
||
| export type AlertDialogContentProps = AlertDialogPopupProps; | ||
|
|
||
| /** | ||
| * Convenience that composes the alert dialog overlay boilerplate — portal, backdrop, centering | ||
| * viewport, and the centered popup — so a consumer only writes the trigger and the popup body. | ||
| */ | ||
| export function AlertDialogContent({ children, ...props }: AlertDialogContentProps) { | ||
| return ( | ||
| <AlertDialogPortal> | ||
| <AlertDialogBackdrop /> | ||
| <AlertDialogViewport> | ||
| <AlertDialogPopup {...props}>{children}</AlertDialogPopup> | ||
| </AlertDialogViewport> | ||
| </AlertDialogPortal> | ||
| ); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.