Skip to content
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

feat: Slider Component #1686

Merged
merged 41 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
1d11929
feat(slider): initial structure
jrgarciadev Sep 24, 2023
ff4b0e2
chore(slider): readme improved
jrgarciadev Sep 24, 2023
f633fdc
fix: fixed border color of slider track
jguddas Sep 24, 2023
990a90b
docs: added range story
jguddas Sep 24, 2023
b162637
feat: added rtl support to slider
jguddas Sep 24, 2023
dda6dec
feat: improved value label formatting
jguddas Sep 24, 2023
ac9cd58
feat: refactor styling and add colors support to slider
jguddas Sep 24, 2023
87bc32f
chore: improved thumb color
jguddas Sep 24, 2023
e23241a
docs: improved slider stories
jguddas Sep 24, 2023
c9e6627
chore(slider): default color changed by foreground
jrgarciadev Sep 24, 2023
3e7a5d2
Update packages/core/theme/src/components/slider.ts
jrgarciadev Sep 24, 2023
43678ee
feat: added fillOffset prop
jguddas Sep 24, 2023
c4ab611
Update packages/components/slider/src/use-slider.ts
jguddas Sep 24, 2023
9c0987b
fix(slider): animation
jrgarciadev Sep 24, 2023
a68f47f
Update packages/components/slider/src/use-slider.ts
jguddas Sep 24, 2023
c9d4c1f
Update packages/core/theme/src/components/slider.ts
jguddas Sep 24, 2023
1eaf52b
feat: slider steps
jguddas Sep 25, 2023
8c6ba2f
refactor: renamed variables
jguddas Sep 25, 2023
679c232
feat: improved slider step styling
jguddas Sep 25, 2023
1cb6f9e
fix: hide infinite steps
jguddas Sep 25, 2023
dbe4967
fix: fixed step transparency issue
jguddas Sep 26, 2023
e48d4f2
fix: fixed thumb focus issue
jguddas Sep 26, 2023
76e653e
Update packages/components/slider/src/use-slider.ts
jguddas Sep 27, 2023
ba1340f
Merge pull request #1693 from nextui-org/feat/slider-steps
jguddas Sep 27, 2023
70da752
Merge branch 'main' of github.com:nextui-org/nextui into feat/slider
jrgarciadev Oct 5, 2023
443c6f1
feat(slider): vertical orientation added, start & end content, bug fixes
jrgarciadev Oct 5, 2023
98208dd
chore(slider): tests added
jrgarciadev Oct 5, 2023
5af4b10
fix(docs): scrollbar added to the sidebar (#1743)
jrgarciadev Oct 5, 2023
58cd924
Merge branch 'main' of github.com:nextui-org/nextui into feat/slider
jrgarciadev Oct 5, 2023
caa811c
feat(slider): marks added
jrgarciadev Oct 5, 2023
bb5ed5d
chore(slider): example ts-doc changed
jrgarciadev Oct 5, 2023
2738495
feat(slider): vertical marks support
jrgarciadev Oct 5, 2023
a9a3437
feat(core): slider tooltip support added, popover modified (#1746)
jrgarciadev Oct 7, 2023
07026da
Feat/slider custom styles (#1751)
jrgarciadev Oct 7, 2023
b4b8f77
Fix/slider tooltip android position (#1753)
jrgarciadev Oct 7, 2023
e41b62f
feat(slider): docs started, custom thumb and custom output stories added
jrgarciadev Oct 8, 2023
abb9398
feat(slider): render function added to custom render the slider parts
jrgarciadev Oct 8, 2023
28e3668
feat(slider): docs in progress, new properties and examples added
jrgarciadev Oct 10, 2023
b1bf5b9
fix(slider): some issues fixed, output renamed to value, documentatio…
jrgarciadev Oct 11, 2023
ba00c75
feat(slider): docs done
jrgarciadev Oct 13, 2023
3433d40
chore: changeset
jrgarciadev Oct 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions .changeset/hip-years-sip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
"@nextui-org/shared-icons": patch
"@nextui-org/popover": patch
"@nextui-org/tooltip": patch
"@nextui-org/select": patch
"@nextui-org/slider": patch
"@nextui-org/badge": patch
"@nextui-org/theme": patch
---

Changes

- Slider tooltip support added

Breaking Changes

- Popover API changed to improve the arrow implementation, arrow is now a pseudo element, this allows the popover to also move the arrow all-together, this change impacts the Popover, Tooltip and Select implementations.

Popover changes:

```diff
<Popover
showArrow
backdrop="opaque"
placement="right"
classNames={{
- base: "py-3 px-4 border border-default-200 bg-gradient-to-br from-white to-default-300 dark:from-default-100 dark:to-default-50",
+ base: [
+ // the "before" pseudo element is now the popover' arrow
+ "before:bg-default-200"
+ ],
- arrow: "bg-default-200",
+ content: [ // now we need to use the "content" slot to actually modify the popover' content styles
+ "py-3 px-4 border border-default-200",
+ "bg-gradient-to-br from-white to-default-300",
+ "dark:from-default-100 dark:to-default-50",
],
}}
>
<PopoverTrigger>
<Button>Open Popover</Button>
</PopoverTrigger>
<PopoverContent>
{(titleProps) => (
<div className="px-1 py-2">
<h3 className="text-small font-bold" {...titleProps}>
Popover Content
</h3>
<div className="text-tiny">This is the popover content</div>
</div>
)}
</PopoverContent>
</Popover>
```

Tooltip changes:

```diff
<Tooltip
showArrow
placement="right"
content="I am a tooltip"
classNames={{
- base: "py-2 px-4 shadow-xl text-black bg-gradient-to-br from-white to-neutral-400",
- arrow: "bg-neutral-400 dark:bg-white",
+ base: [
+ // the "before" pseudo element is now the popover' arrow
+ "before:bg-neutral-400 dark:before:bg-white",
+ ],
+ content: [ // now we need to use the "content" slot to actually modify the popover' content styles
+ "py-2 px-4 shadow-xl",
+ "text-black bg-gradient-to-br from-white to-neutral-400",
+ ],
}}
>
<Button variant="flat">Hover me</Button>
</Tooltip>
```

Select changes:

```diff
<Select
items={users}
label="Assigned to"
className="max-w-xs"
variant="bordered"
classNames={{
label: "group-data-[filled=true]:-translate-y-5",
trigger: "min-h-unit-16",
listboxWrapper: "max-h-[400px]",
}}
listboxProps={{
itemClasses: {
base: [
"rounded-md",
"text-default-500",
"transition-opacity",
"data-[hover=true]:text-foreground",
"data-[hover=true]:bg-default-100",
"dark:data-[hover=true]:bg-default-50",
"data-[selectable=true]:focus:bg-default-50",
"data-[pressed=true]:opacity-70",
"data-[focus-visible=true]:ring-default-500",
],
},
}}
popoverProps={{
classNames: {
- base: "p-0 border-small border-divider bg-background",
- arrow: "bg-default-200",
+ base: "before:bg-default-200", // the before pseudo element controls the popover's arrow
+ content: "p-0 border-small border-divider bg-background", // now instead of the "base" slot we use the "content" slot
},
}}
renderValue={(items) => {
return items.map((item) => (
<div key={item.key} className="flex items-center gap-2">
<Avatar
alt={item.data.name}
className="flex-shrink-0"
size="sm"
src={item.data.avatar}
/>
<div className="flex flex-col">
<span>{item.data.name}</span>
<span className="text-default-500 text-tiny">({item.data.email})</span>
</div>
</div>
));
}}
>
{(user) => (
<SelectItem key={user.id} textValue={user.name}>
<div className="flex gap-2 items-center">
<Avatar alt={user.name} className="flex-shrink-0" size="sm" src={user.avatar} />
<div className="flex flex-col">
<span className="text-small">{user.name}</span>
<span className="text-tiny text-default-400">{user.email}</span>
</div>
</div>
</SelectItem>
)}
</Select>
);
}`;
```
16 changes: 16 additions & 0 deletions .changeset/stupid-experts-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@nextui-org/react-rsc-utils": patch
"@nextui-org/shared-icons": patch
"@nextui-org/dropdown": patch
"@nextui-org/popover": patch
"@nextui-org/snippet": patch
"@nextui-org/tooltip": patch
"@nextui-org/select": patch
"@nextui-org/slider": patch
"@nextui-org/badge": patch
"@nextui-org/react": patch
"@nextui-org/theme": patch
---

- New component: Slider
- Arrow removed from the popover styles and code as well as from related components such as Tooltip, Snippet and Select
2 changes: 1 addition & 1 deletion apps/docs/app/docs/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function DocsLayout({children}: DocsLayoutProps) {
<>
<main className="relative container mx-auto max-w-7xl z-10 px-6 min-h-[calc(100vh_-_64px_-_108px)] mb-12 flex-grow">
<div className="grid grid-cols-12">
<div className="hidden relative z-10 lg:block lg:col-span-2 mt-8 pr-4">
<div className="hidden overflow-visible relative z-10 lg:block lg:col-span-2 mt-8 pr-4">
<DocsSidebar routes={manifest.routes} />
</div>
{children}
Expand Down
36 changes: 20 additions & 16 deletions apps/docs/components/docs/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ import Link from "next/link";
import {isEmpty} from "lodash";
import {usePathname, useRouter} from "next/navigation";

import {ScrollArea} from "../scroll-area";

import {getRoutePaths} from "./utils";

import {Route} from "@/libs/docs/page";
import {TreeKeyboardDelegate} from "@/utils/tree-keyboard-delegate";
import {useScrollPosition} from "@/hooks/use-scroll-position";
import {trackEvent} from "@/utils/va";

export interface Props<T> extends Omit<ItemProps<T>, "title">, Route {
Expand Down Expand Up @@ -69,6 +70,7 @@ function TreeItem<T>(props: TreeItemProps<T>) {
};

const isNew = item.props?.newPost;
const isUpdated = item.props?.updated;

const isExpanded = state.expandedKeys.has(key);
const isSelected =
Expand Down Expand Up @@ -108,7 +110,9 @@ function TreeItem<T>(props: TreeItemProps<T>) {
aria-expanded={dataAttr(hasChildNodes ? isExpanded : undefined)}
aria-selected={dataAttr(isSelected)}
className={clsx(
"flex flex-col gap-3 outline-none w-full tap-highlight-transparent",
"flex flex-col gap-3outline-none w-full tap-highlight-transparent",

hasChildNodes ? "mb-4" : "first:mt-4",
// focus ring
...dataFocusVisibleClasses,
)}
Expand Down Expand Up @@ -156,18 +160,25 @@ function TreeItem<T>(props: TreeItemProps<T>) {
>
{rendered}
</span>
{isUpdated && (
<Chip className="ml-1 py-1 text-tiny" color="default" size="sm" variant="flat">
Updated
</Chip>
)}
{isNew && (
<Chip className="ml-2" color="primary" size="sm" variant="flat">
<Chip className="ml-1 py-1 text-tiny" color="primary" size="sm" variant="flat">
New
</Chip>
)}
{item.props?.comingSoon && (
<Chip className="ml-2" color="default" size="sm" variant="flat">
<Chip className="ml-1 py-1 text-tiny" color="default" size="sm" variant="flat">
Coming soon
</Chip>
)}
</NextUILink>
)}
{/* Workaround to avoid scrollbar overlapping */}
<Spacer x={4} />
</div>
{isExpanded && hasChildNodes && (
<div className="flex flex-col gap-3 items-start" role="group">
Expand Down Expand Up @@ -196,9 +207,7 @@ function TreeHeading({item}: {item: any}) {
function Tree<T extends object>(props: CollectionBase<T> & Expandable & MultipleSelection) {
let state = useTreeState(props);

let ref = useRef<HTMLUListElement>(null);

const scrollPosition = useScrollPosition(ref);
let ref = useRef<HTMLDivElement>(null);

let keyboardDelegate = useMemo(
// @ts-expect-error
Expand All @@ -213,16 +222,11 @@ function Tree<T extends object>(props: CollectionBase<T> & Expandable & Multiple
});

return (
<ul
{...collectionProps}
<ScrollArea
ref={ref}
className="flex flex-col gap-4 scrollbar-hide lg:overflow-y-scroll lg:max-h-[calc(100vh_-_64px)] pb-28"
className="h-full lg:max-h-[calc(100vh_-_64px)]"
role="tree"
style={{
WebkitMaskImage: `linear-gradient(to top, transparent 0%, #000 100px, #000 ${
scrollPosition > 30 ? "90%" : "100%"
}, transparent 100%)`,
}}
{...collectionProps}
>
{[...state.collection].map((item) => {
if (item.type === "section") {
Expand All @@ -231,7 +235,7 @@ function Tree<T extends object>(props: CollectionBase<T> & Expandable & Multiple

return <TreeItem key={item.key} item={item} state={state} />;
})}
</ul>
</ScrollArea>
);
}

Expand Down
54 changes: 54 additions & 0 deletions apps/docs/components/scroll-area.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"use client";

import * as React from "react";
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
import {cn} from "@nextui-org/react";

const ScrollArea = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
>(({className, children, ...props}, ref) => {
return (
<ScrollAreaPrimitive.Root
ref={ref}
className={cn("relative overflow-hidden", className)}
{...props}
>
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit] pb-28">
{children}
</ScrollAreaPrimitive.Viewport>
<ScrollBar />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
);
});

ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;

const ScrollBar = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
>(({className, orientation = "vertical", ...props}, ref) => (
<ScrollAreaPrimitive.ScrollAreaScrollbar
ref={ref}
className={cn(
"flex touch-none select-none transition-colors",
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
orientation === "horizontal" && "h-2.5 border-t border-t-transparent p-[1px]",
className,
)}
orientation={orientation}
{...props}
>
<ScrollAreaPrimitive.ScrollAreaThumb
className={cn(
"relative rounded-full bg-default-400/50",
orientation === "vertical" && "flex-1",
)}
/>
</ScrollAreaPrimitive.ScrollAreaScrollbar>
));

ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;

export {ScrollArea, ScrollBar};
16 changes: 10 additions & 6 deletions apps/docs/config/routes.json
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,7 @@
"key": "listbox",
"title": "Listbox",
"keywords": "listbox, selection, option list, multiple choice",
"path": "/docs/components/listbox.mdx",
"newPost": true
"path": "/docs/components/listbox.mdx"
},
{
"key": "modal",
Expand Down Expand Up @@ -261,8 +260,7 @@
"key": "select",
"title": "Select",
"keywords": "select, selection, option list, multiple choice",
"path": "/docs/components/select.mdx",
"newPost": true
"path": "/docs/components/select.mdx"
},
{
"key": "skeleton",
Expand All @@ -280,8 +278,7 @@
"key": "scroll-shadow",
"title": "Scroll Shadow",
"keywords": "scroll shadow, scroll indicator, scroll bar, scroll position",
"path": "/docs/components/scroll-shadow.mdx",
"newPost": true
"path": "/docs/components/scroll-shadow.mdx"
},
{
"key": "spacer",
Expand All @@ -301,6 +298,13 @@
"keywords": "switch, toggle, binary input, on/off control",
"path": "/docs/components/switch.mdx"
},
{
"key": "slider",
"title": "Slider",
"keywords": "slider, range input, value selector, sliding control",
"path": "/docs/components/slider.mdx",
"newPost": true
},
{
"key": "table",
"title": "Table",
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/components/badge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import placements from "./placements";
import shapes from "./shapes";
import visibility from "./visibility";
import contentExamples from "./content-examples";
import disableOutline from "./disable-outline";
import showOutline from "./show-outline";
import a11y from "./a11y";

export const badgeContent = {
Expand All @@ -18,6 +18,6 @@ export const badgeContent = {
shapes,
visibility,
contentExamples,
disableOutline,
showOutline,
a11y,
};
Loading
Loading