diff --git a/apps/www/src/components/playground/filter-card-examples.tsx b/apps/www/src/components/playground/filter-card-examples.tsx new file mode 100644 index 00000000..533dff96 --- /dev/null +++ b/apps/www/src/components/playground/filter-card-examples.tsx @@ -0,0 +1,55 @@ +'use client'; + +import { Button, FilterCard, Select, Text } from '@raystack/apsara'; +import PlaygroundLayout from './playground-layout'; + +export function FilterCardExamples() { + return ( + + + + + + + + + + + + Name, Creator, Project + + + + + + + ); +} diff --git a/apps/www/src/components/playground/index.ts b/apps/www/src/components/playground/index.ts index 3f657dd3..f5ab6d71 100644 --- a/apps/www/src/components/playground/index.ts +++ b/apps/www/src/components/playground/index.ts @@ -16,6 +16,7 @@ export * from './data-table-examples'; export * from './dialog-examples'; export * from './dropdown-menu-examples'; export * from './empty-state-examples'; +export * from './filter-card-examples'; export * from './filter-chip-examples'; export * from './flex-examples'; export * from './headline-examples'; diff --git a/apps/www/src/content/docs/components/filter-card/demo.ts b/apps/www/src/content/docs/components/filter-card/demo.ts new file mode 100644 index 00000000..1419c4fa --- /dev/null +++ b/apps/www/src/content/docs/components/filter-card/demo.ts @@ -0,0 +1,74 @@ +'use client'; + +import { getPropsString } from '@/lib/utils'; + +export const getCode = (props: any) => { + const { children, ...rest } = props; + return ` + ${children} +`; +}; + +export const playground = { + type: 'playground', + controls: { + title: { + type: 'text', + initialValue: 'Display Properties' + }, + children: { + type: 'text', + initialValue: 'Section content goes here' + } + }, + getCode +}; + +export const sectionsDemo = { + type: 'code', + code: ` + + + + + + + + + + + Name, Creator, Project + + + + + ` +}; + +export const withoutTitleDemo = { + type: 'code', + code: ` + + + Section without a title + + ` +}; diff --git a/apps/www/src/content/docs/components/filter-card/index.mdx b/apps/www/src/content/docs/components/filter-card/index.mdx new file mode 100644 index 00000000..bdaf6d56 --- /dev/null +++ b/apps/www/src/content/docs/components/filter-card/index.mdx @@ -0,0 +1,71 @@ +--- +title: FilterCard +description: A sectioned card component for grouping filter controls and configuration options. +source: packages/raystack/components/filter-card +--- + +import { playground, sectionsDemo, withoutTitleDemo } from "./demo.ts"; + + + +## Anatomy + +Import and assemble the component: + +```tsx +import { FilterCard } from '@raystack/apsara' + + + + + Action content + + + + Content + + + Footer content + + +``` + +## API Reference + +### FilterCard + +The outer container for the filter card. + + + +### FilterCard.Section + +A section within the filter card with an optional title. + + + +### FilterCard.Item + +A label-action row within a section. + + + +### FilterCard.Footer + +A compact footer section, right-aligned by default. + + + +## Examples + +### With Sections + +Multiple sections separated by a divider: + + + +### Without Title + +Sections can be rendered without a title: + + diff --git a/apps/www/src/content/docs/components/filter-card/props.ts b/apps/www/src/content/docs/components/filter-card/props.ts new file mode 100644 index 00000000..751014fd --- /dev/null +++ b/apps/www/src/content/docs/components/filter-card/props.ts @@ -0,0 +1,75 @@ +export interface FilterCardProps { + /** Content of the filter card */ + children?: React.ReactNode; + + /** Additional CSS class names */ + className?: string; +} + +export interface FilterCardSectionProps { + /** Optional title for the section */ + title?: string; + + /** Content of the section */ + children?: React.ReactNode; + + /** Additional CSS class names */ + className?: string; + + /** + * Flex direction + * @defaultValue "column" + */ + direction?: 'row' | 'column' | 'rowReverse' | 'columnReverse'; + + /** Flex align items */ + align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline'; + + /** Flex justify content */ + justify?: 'start' | 'center' | 'end' | 'between'; + + /** Flex wrap */ + wrap?: 'noWrap' | 'wrap' | 'wrapReverse'; + + /** Flex gap */ + gap?: + | 1 + | 2 + | 3 + | 4 + | 5 + | 6 + | 7 + | 8 + | 9 + | 'extra-small' + | 'small' + | 'medium' + | 'large' + | 'extra-large'; +} + +export interface FilterCardItemProps { + /** Label text displayed on the left */ + label: string; + + /** Action content displayed on the right */ + children?: React.ReactNode; + + /** Additional CSS class names */ + className?: string; +} + +export interface FilterCardFooterProps { + /** Content of the footer */ + children?: React.ReactNode; + + /** Additional CSS class names */ + className?: string; + + /** + * Flex justify content + * @defaultValue "end" + */ + justify?: 'start' | 'center' | 'end' | 'between'; +} diff --git a/apps/www/src/content/docs/components/popover/props.ts b/apps/www/src/content/docs/components/popover/props.ts index 4887dfff..0f83001e 100644 --- a/apps/www/src/content/docs/components/popover/props.ts +++ b/apps/www/src/content/docs/components/popover/props.ts @@ -13,6 +13,12 @@ export interface PopoverRootProps { } export interface PopoverContentProps { + /** + * Visual style variant + * @defaultValue "default" + */ + variant?: 'default' | 'unstyled'; + /** Preferred side of the trigger to render. */ side?: 'top' | 'right' | 'bottom' | 'left'; diff --git a/packages/raystack/components/data-table/components/display-properties.tsx b/packages/raystack/components/data-table/components/display-properties.tsx index 8ce8e892..e3a02e5a 100644 --- a/packages/raystack/components/data-table/components/display-properties.tsx +++ b/packages/raystack/components/data-table/components/display-properties.tsx @@ -2,7 +2,6 @@ import { Chip } from '../../chip'; import { Flex } from '../../flex'; -import { Text } from '../../text'; import { DataTableColumn } from '../data-table.types'; export function DisplayProperties({ @@ -13,21 +12,18 @@ export function DisplayProperties({ const hidableColumns = columns?.filter(col => col.columnDef.enableHiding); return ( - - Display Properties - - {hidableColumns.map(column => ( - column.toggleVisibility()} - > - {(column.columnDef.header as string) || column.id} - - ))} - + + {hidableColumns.map(column => ( + column.toggleVisibility()} + > + {(column.columnDef.header as string) || column.id} + + ))} ); } diff --git a/packages/raystack/components/data-table/components/display-settings.tsx b/packages/raystack/components/data-table/components/display-settings.tsx index a25f1bcc..fc889f87 100644 --- a/packages/raystack/components/data-table/components/display-settings.tsx +++ b/packages/raystack/components/data-table/components/display-settings.tsx @@ -4,13 +4,12 @@ import { MixerHorizontalIcon } from '@radix-ui/react-icons'; import { ReactNode } from 'react'; import { Button } from '../../button'; -import { Flex } from '../../flex'; +import { FilterCard } from '../../filter-card'; import { Popover } from '../../popover'; -import styles from '../data-table.module.css'; import { DataTableColumn, - SortOrdersValues, - defaultGroupOption + defaultGroupOption, + SortOrdersValues } from '../data-table.types'; import { useDataTable } from '../hooks/useDataTable'; import { DisplayProperties } from './display-properties'; @@ -86,16 +85,9 @@ export function DisplaySettings({ return ( {trigger} - - - + + + ({ onChange={onGroupChange} value={tableQuery?.group_by?.[0] || defaultGroupOption.id} /> - - + + - - + + - - + + ); diff --git a/packages/raystack/components/data-table/components/grouping.tsx b/packages/raystack/components/data-table/components/grouping.tsx index ce5c6db1..32c7e397 100644 --- a/packages/raystack/components/data-table/components/grouping.tsx +++ b/packages/raystack/components/data-table/components/grouping.tsx @@ -1,8 +1,7 @@ 'use client'; -import { Flex } from '../../flex'; +import { FilterCard } from '../../filter-card'; import { Select } from '../../select'; -import { Text } from '../../text'; import styles from '../data-table.module.css'; import { DataTableColumn, defaultGroupOption } from '../data-table.types'; @@ -41,30 +40,25 @@ export function Grouping({ }; return ( - - - Grouping - - - + + + + + + {defaultGroupOption.label} + + {columnList.map(column => ( + + {column.label} - {columnList.map(column => ( - - {column.label} - - ))} - - - - + ))} + + + ); } diff --git a/packages/raystack/components/data-table/components/ordering.tsx b/packages/raystack/components/data-table/components/ordering.tsx index abebe5b5..0d0fb2aa 100644 --- a/packages/raystack/components/data-table/components/ordering.tsx +++ b/packages/raystack/components/data-table/components/ordering.tsx @@ -2,10 +2,10 @@ import { TextAlignBottomIcon, TextAlignTopIcon } from '@radix-ui/react-icons'; +import { FilterCard } from '../../filter-card'; import { Flex } from '../../flex'; import { IconButton } from '../../icon-button'; import { Select } from '../../select'; -import { Text } from '../../text'; import styles from '../data-table.module.css'; import { ColumnData, @@ -32,11 +32,8 @@ export function Ordering({ columnList, onChange, value }: OrderingProps) { } return ( - - - Ordering - - + +