diff --git a/lib/platform-bible-react/src/components/advanced/book-chapter-control/book-chapter-control.component.tsx b/lib/platform-bible-react/src/components/advanced/book-chapter-control/book-chapter-control.component.tsx index 0c25bf9eab..0bab6e4a08 100644 --- a/lib/platform-bible-react/src/components/advanced/book-chapter-control/book-chapter-control.component.tsx +++ b/lib/platform-bible-react/src/components/advanced/book-chapter-control/book-chapter-control.component.tsx @@ -11,7 +11,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/shadcn-ui/dropdown-menu'; -import { cn } from '@/utils/shadcn-ui.util'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; import { Canon } from '@sillsdev/scripture'; import { ScriptureReference, getChaptersForBook } from 'platform-bible-utils'; import { @@ -29,8 +29,6 @@ type BookTypeLabels = { type BookChapterControlProps = { scrRef: ScriptureReference; handleSubmit: (scrRef: ScriptureReference) => void; - /** Text and layout direction */ - direction?: 'rtl' | 'ltr'; }; const ALL_BOOK_IDS = Canon.allBookIds; @@ -104,7 +102,8 @@ function getBookIdFromEnglishName(bookName: string): string | undefined { return undefined; } -function BookChapterControl({ scrRef, handleSubmit, direction }: BookChapterControlProps) { +function BookChapterControl({ scrRef, handleSubmit }: BookChapterControlProps) { + const dir: Direction = readDirection(); const [searchQuery, setSearchQuery] = useState(''); const [selectedBookId, setSelectedBookId] = useState( Canon.bookNumberToId(scrRef.bookNum), @@ -263,13 +262,13 @@ function BookChapterControl({ scrRef, handleSubmit, direction }: BookChapterCont } const upOneChapter = - (key === 'ArrowRight' && !direction) || - (key === 'ArrowRight' && direction === 'ltr') || - (key === 'ArrowLeft' && direction === 'rtl'); + (key === 'ArrowRight' && !dir) || + (key === 'ArrowRight' && dir === 'ltr') || + (key === 'ArrowLeft' && dir === 'rtl'); const downOneChapter = - (key === 'ArrowLeft' && !direction) || - (key === 'ArrowLeft' && direction === 'ltr') || - (key === 'ArrowRight' && direction === 'rtl'); + (key === 'ArrowLeft' && !dir) || + (key === 'ArrowLeft' && dir === 'ltr') || + (key === 'ArrowRight' && dir === 'rtl'); let chapterOffSet = 0; if (upOneChapter) { if (highlightedChapter < fetchEndChapter(highlightedBookId)) { @@ -355,7 +354,6 @@ function BookChapterControl({ scrRef, handleSubmit, direction }: BookChapterCont }} handleSubmit={handleInputSubmit} placeholder={`${Canon.bookNumberToEnglishName(scrRef.bookNum)} ${scrRef.chapterNum}:${scrRef.verseNum}`} - direction={direction} /> {/* work around until DropdownMenuContent supports a dir prop */} -
+
console.log('sorting')} handleLocationHistory={() => console.log('location history')} @@ -393,7 +391,6 @@ function BookChapterControl({ scrRef, handleSubmit, direction }: BookChapterCont ref={(element: HTMLDivElement) => { if (selectedBookId === bookId) menuItemRef.current = element; }} - direction={direction} > void; @@ -11,23 +12,15 @@ export type BookChapterInputProps = { onFocus?: FocusEventHandler; value: string; placeholder: string; - /** Text and layout direction */ - direction?: 'rtl' | 'ltr'; }; // Shadcn Input sets type to "button"- HAVE to prop spread before setting type const BookChapterInput = forwardRef( ( - { - handleSearch, - handleKeyDown, - handleOnClick, - handleSubmit, - direction = 'ltr', - ...props - }: BookChapterInputProps, + { handleSearch, handleKeyDown, handleOnClick, handleSubmit, ...props }: BookChapterInputProps, ref, ) => { + const dir: Direction = readDirection(); return (
( { // eslint-disable-next-line no-console diff --git a/lib/platform-bible-react/src/components/advanced/book-chapter-control/book-menu-item.component.tsx b/lib/platform-bible-react/src/components/advanced/book-chapter-control/book-menu-item.component.tsx index e8b70d3512..72d88a320b 100644 --- a/lib/platform-bible-react/src/components/advanced/book-chapter-control/book-menu-item.component.tsx +++ b/lib/platform-bible-react/src/components/advanced/book-chapter-control/book-menu-item.component.tsx @@ -2,6 +2,7 @@ import { Canon } from '@sillsdev/scripture'; import { PropsWithChildren, KeyboardEvent, forwardRef } from 'react'; import { DropdownMenuItem } from '@/components/shadcn-ui/dropdown-menu'; import { cn } from '@/utils/shadcn-ui.util'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; export type BookType = 'OT' | 'NT' | 'DC'; @@ -25,8 +26,6 @@ type BookMenuItemProps = PropsWithChildren<{ * coordinated to genre */ bookType: BookType; - /** Text and layout direction */ - direction?: 'rtl' | 'ltr'; }>; const BookMenuItem = forwardRef( @@ -39,19 +38,22 @@ const BookMenuItem = forwardRef( handleKeyDown, bookType, children, - direction, }: BookMenuItemProps, ref, ) => { + const dir: Direction = readDirection(); return ( { // preventDefault() here prevents the entire dropdown menu from closing when selecting this item event.preventDefault(); @@ -62,7 +64,7 @@ const BookMenuItem = forwardRef( }} onFocus={handleHighlightBook} onMouseMove={handleHighlightBook} - dir={direction} + dir={dir} > onSelectionModeChange(value as BookSelectionMode)} - dir={direction} >
@@ -101,7 +99,6 @@ export default function BookSelector({ chapterCount={chapterCount} startChapter={startChapter} endChapter={endChapter} - direction={direction} />
diff --git a/lib/platform-bible-react/src/components/advanced/inventory/inventory-columns.tsx b/lib/platform-bible-react/src/components/advanced/inventory/inventory-columns.tsx index 85554a14d7..cca0bff68e 100644 --- a/lib/platform-bible-react/src/components/advanced/inventory/inventory-columns.tsx +++ b/lib/platform-bible-react/src/components/advanced/inventory/inventory-columns.tsx @@ -1,6 +1,7 @@ import { ColumnDef, SortDirection } from '@/components/advanced/data-table/data-table.component'; import { Button } from '@/components/shadcn-ui/button'; import { ToggleGroup, ToggleGroupItem } from '@/components/shadcn-ui/toggle-group'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; import { ArrowDownIcon, ArrowUpDownIcon, @@ -157,7 +158,6 @@ export const inventoryStatusColumn = ( onApprovedItemsChange: (items: string[]) => void, unapprovedItems: string[], onUnapprovedItemsChange: (items: string[]) => void, - direction: 'rtl' | 'ltr' = 'ltr', ): ColumnDef => { return { accessorKey: 'status', @@ -174,8 +174,9 @@ export const inventoryStatusColumn = ( cell: ({ row }) => { const status: Status = row.getValue('status'); const item: string = row.getValue('item'); + const dir: Direction = readDirection(); return ( - + statusChangeHandler( diff --git a/lib/platform-bible-react/src/components/advanced/inventory/inventory.component.tsx b/lib/platform-bible-react/src/components/advanced/inventory/inventory.component.tsx index 12622c0b46..a2e6bc3ac4 100644 --- a/lib/platform-bible-react/src/components/advanced/inventory/inventory.component.tsx +++ b/lib/platform-bible-react/src/components/advanced/inventory/inventory.component.tsx @@ -32,6 +32,7 @@ import { Status, } from './inventory-utils'; import { inventoryAdditionalItemColumn } from './inventory-columns'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; /** * Object containing all keys used for localization in this component. If you're using this @@ -245,8 +246,6 @@ type InventoryProps = { * other columns you can add these yourself */ columns: ColumnDef[]; - /** Text and layout direction */ - direction?: 'rtl' | 'ltr'; }; /** Inventory component that is used to view and control the status of provided project settings */ @@ -262,7 +261,6 @@ export default function Inventory({ scope, onScopeChange, columns, - direction, }: InventoryProps) { const allItemsText = localizeString(localizedStrings, '%webView_inventory_all%'); const approvedItemsText = localizeString(localizedStrings, '%webView_inventory_approved%'); @@ -392,13 +390,15 @@ export default function Inventory({ return occurrence[0].occurrences; }, [selectedItem, showAdditionalItems, reducedTableData]); + const dir: Direction = readDirection(); + return (
- handleScopeChange(value)} defaultValue={scope} dir={dir}> diff --git a/lib/platform-bible-react/src/components/advanced/multi-select-combo-box.tsx b/lib/platform-bible-react/src/components/advanced/multi-select-combo-box.tsx index ad644f7177..3d19459abc 100644 --- a/lib/platform-bible-react/src/components/advanced/multi-select-combo-box.tsx +++ b/lib/platform-bible-react/src/components/advanced/multi-select-combo-box.tsx @@ -28,8 +28,6 @@ interface MultiSelectComboBoxProps { customSelectedText?: string; sortSelected?: boolean; icon?: ReactNode; - /** Text and layout direction */ - direction?: 'rtl' | 'ltr'; } function MultiSelectComboBox({ @@ -42,7 +40,6 @@ function MultiSelectComboBox({ customSelectedText, sortSelected = false, icon = undefined, - direction = 'ltr', }: MultiSelectComboBoxProps) { const [open, setOpen] = useState(false); @@ -112,7 +109,7 @@ function MultiSelectComboBox({ - + diff --git a/lib/platform-bible-react/src/components/advanced/scripture-results-viewer/scripture-results-viewer.component.tsx b/lib/platform-bible-react/src/components/advanced/scripture-results-viewer/scripture-results-viewer.component.tsx index c4f74ae548..df9f434d4e 100644 --- a/lib/platform-bible-react/src/components/advanced/scripture-results-viewer/scripture-results-viewer.component.tsx +++ b/lib/platform-bible-react/src/components/advanced/scripture-results-viewer/scripture-results-viewer.component.tsx @@ -40,6 +40,7 @@ import { } from 'platform-bible-utils'; import { MouseEvent, useEffect, useMemo, useState } from 'react'; import { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; /** * Information (e.g., a checking error or some other type of "transient" annotation) about something @@ -137,9 +138,6 @@ export type ScriptureResultsViewerProps = ScriptureResultsViewerColumnInfo & { /** Callback function to notify when a row is selected */ onRowSelected?: (selectedRow: ScriptureSrcItemDetail | undefined) => void; - - /** Text direction ltr or rtl */ - direction?: 'ltr' | 'rtl'; }; function getColumns( @@ -236,7 +234,6 @@ export default function ScriptureResultsViewer({ typeColumnName, detailsColumnName, onRowSelected, - direction = 'ltr', }: ScriptureResultsViewerProps) { const [grouping, setGrouping] = useState([]); const [sorting, setSorting] = useState([{ id: scrBookColId, desc: false }]); @@ -379,7 +376,6 @@ export default function ScriptureResultsViewer({ onValueChange={(value) => { handleSelectChange(value); }} - dir={direction} > @@ -428,6 +424,7 @@ export default function ScriptureResultsViewer({ )} {table.getRowModel().rows.map((row, rowIndex) => { + const dir: Direction = readDirection(); return ( {row.getIsExpanded() && } {!row.getIsExpanded() && - (direction === 'ltr' ? : )}{' '} + (dir === 'ltr' ? : )}{' '} {flexRender(cell.column.columnDef.cell, cell.getContext())} ( {row.subRows.length}) diff --git a/lib/platform-bible-react/src/components/advanced/scroll-group-selector.component.tsx b/lib/platform-bible-react/src/components/advanced/scroll-group-selector.component.tsx index 4751fd51f3..af93b91bf9 100644 --- a/lib/platform-bible-react/src/components/advanced/scroll-group-selector.component.tsx +++ b/lib/platform-bible-react/src/components/advanced/scroll-group-selector.component.tsx @@ -10,6 +10,7 @@ import { SelectTrigger, SelectValue, } from '@/components/shadcn-ui/select'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; const DEFAULT_SCROLL_GROUP_LOCALIZED_STRINGS = { [getLocalizeKeyForScrollGroupId('undefined')]: 'Ø', @@ -91,8 +92,6 @@ export type ScrollGroupSelectorProps = { * ``` */ localizedStrings?: LanguageStrings; - /** Text and layout direction */ - direction?: 'rtl' | 'ltr'; }; /** Selector component for choosing a scroll group */ @@ -101,7 +100,6 @@ export default function ScrollGroupSelector({ scrollGroupId, onChangeScrollGroupId, localizedStrings = {}, - direction = 'ltr', }: ScrollGroupSelectorProps) { const localizedStringsDefaulted = { ...DEFAULT_SCROLL_GROUP_LOCALIZED_STRINGS, @@ -117,6 +115,9 @@ export default function ScrollGroupSelector({ ), ), }; + + const dir: Direction = readDirection(); + return ( ( - ({ className, direction, ...props }, ref) => { - return ( - - ); - }, -); +const Spinner = forwardRef(({ className, ...props }, ref) => { + return ( + + ); +}); Spinner.displayName = 'Spinner'; diff --git a/lib/platform-bible-react/src/components/basics/tabs-vertical.tsx b/lib/platform-bible-react/src/components/basics/tabs-vertical.tsx index 442625d119..7d5f74483d 100644 --- a/lib/platform-bible-react/src/components/basics/tabs-vertical.tsx +++ b/lib/platform-bible-react/src/components/basics/tabs-vertical.tsx @@ -3,6 +3,7 @@ 'use client'; import { TabsContentProps, TabsListProps, TabsTriggerProps } from '@/components/shadcn-ui/tabs'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; import { cn } from '@/utils/shadcn-ui.util'; import * as TabsPrimitive from '@radix-ui/react-tabs'; import React from 'react'; @@ -19,14 +20,18 @@ export type LeftTabsTriggerProps = TabsTriggerProps & { export const VerticalTabs = React.forwardRef< React.ElementRef, VerticalTabsProps ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const dir: Direction = readDirection(); + return ( + + ); +}); VerticalTabs.displayName = TabsPrimitive.List.displayName; diff --git a/lib/platform-bible-react/src/components/shadcn-ui/command.tsx b/lib/platform-bible-react/src/components/shadcn-ui/command.tsx index fe88d5c8ff..38d39f2b89 100644 --- a/lib/platform-bible-react/src/components/shadcn-ui/command.tsx +++ b/lib/platform-bible-react/src/components/shadcn-ui/command.tsx @@ -5,6 +5,7 @@ import { Search } from 'lucide-react'; import { cn } from '@/utils/shadcn-ui.util'; import { Dialog, DialogContent } from '@/components/shadcn-ui/dialog'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; const Command = React.forwardRef< React.ElementRef, @@ -38,19 +39,22 @@ function CommandDialog({ children, ...props }: CommandDialogProps) { const CommandInput = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( -
- - -
-)); +>(({ className, ...props }, ref) => { + const dir: Direction = readDirection(); + return ( +
+ + +
+ ); +}); CommandInput.displayName = CommandPrimitive.Input.displayName; diff --git a/lib/platform-bible-react/src/components/shadcn-ui/dialog.tsx b/lib/platform-bible-react/src/components/shadcn-ui/dialog.tsx index ec044c9a71..fb8b2e2c15 100644 --- a/lib/platform-bible-react/src/components/shadcn-ui/dialog.tsx +++ b/lib/platform-bible-react/src/components/shadcn-ui/dialog.tsx @@ -3,6 +3,7 @@ import * as DialogPrimitive from '@radix-ui/react-dialog'; import { X } from 'lucide-react'; import { cn } from '@/utils/shadcn-ui.util'; +import { readDirection } from '@/utils/dir-helper.util'; const Dialog = DialogPrimitive.Root; @@ -27,34 +28,46 @@ const DialogOverlay = React.forwardRef< )); DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; -/* TODO: bug in shadcn dialog: header and x icon do not make use of the dir prop */ const DialogContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - - - {children} - - - Close - - - -)); +>(({ className, children, ...props }, ref) => { + const dir = readDirection(); + return ( + + + + {children} + + + Close + + + + ); +}); DialogContent.displayName = DialogPrimitive.Content.displayName; function DialogHeader({ className, ...props }: React.HTMLAttributes) { return (
); diff --git a/lib/platform-bible-react/src/components/shadcn-ui/dropdown-menu.tsx b/lib/platform-bible-react/src/components/shadcn-ui/dropdown-menu.tsx index 3becc90aad..e958090735 100644 --- a/lib/platform-bible-react/src/components/shadcn-ui/dropdown-menu.tsx +++ b/lib/platform-bible-react/src/components/shadcn-ui/dropdown-menu.tsx @@ -3,6 +3,7 @@ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'; import { Check, ChevronRight, Circle } from 'lucide-react'; import { cn } from '@/utils/shadcn-ui.util'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; export const DropdownMenu = DropdownMenuPrimitive.Root; @@ -113,26 +114,27 @@ the scrollbar to appear left in an rtl layout (e.g. see book-chapter-control.com export const DropdownMenuContent = React.forwardRef< React.ElementRef, DropdownMenuContentProps ->(({ className, sideOffset = 4, ...props }, ref) => ( - - - -)); +>(({ className, sideOffset = 4, children, ...props }, ref) => { + const dir: Direction = readDirection(); + return ( + + +
{children}
+
+
+ ); +}); DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName; -/** - * TODO: fix: direction is not automatically handled by this component, so that shortcuts are - * display always to the right - */ export const DropdownMenuItem = React.forwardRef< React.ElementRef, DropdownMenuItemProps @@ -140,8 +142,8 @@ export const DropdownMenuItem = React.forwardRef< - + @@ -180,12 +182,12 @@ export const DropdownMenuRadioItem = React.forwardRef< - + @@ -222,7 +224,7 @@ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; export function DropdownMenuShortcut({ className, ...props }: DropdownMenuShortcutProps) { return ( diff --git a/lib/platform-bible-react/src/components/shadcn-ui/popover.tsx b/lib/platform-bible-react/src/components/shadcn-ui/popover.tsx index da8b7889ba..2cc37d6016 100644 --- a/lib/platform-bible-react/src/components/shadcn-ui/popover.tsx +++ b/lib/platform-bible-react/src/components/shadcn-ui/popover.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import * as PopoverPrimitive from '@radix-ui/react-popover'; +import React from 'react'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; import { cn } from '@/utils/shadcn-ui.util'; const Popover = PopoverPrimitive.Root; @@ -10,20 +11,24 @@ const PopoverTrigger = PopoverPrimitive.Trigger; const PopoverContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, align = 'center', sideOffset = 4, ...props }, ref) => ( - - - -)); +>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => { + const dir: Direction = readDirection(); + return ( + + + + ); +}); PopoverContent.displayName = PopoverPrimitive.Content.displayName; -export { Popover, PopoverTrigger, PopoverContent }; +export { Popover, PopoverContent, PopoverTrigger }; diff --git a/lib/platform-bible-react/src/components/shadcn-ui/radio-group.tsx b/lib/platform-bible-react/src/components/shadcn-ui/radio-group.tsx index e422c24c05..9264f9ce9e 100644 --- a/lib/platform-bible-react/src/components/shadcn-ui/radio-group.tsx +++ b/lib/platform-bible-react/src/components/shadcn-ui/radio-group.tsx @@ -3,16 +3,19 @@ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group'; import { Circle } from 'lucide-react'; import { cn } from '@/utils/shadcn-ui.util'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; const RadioGroup = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { + const dir: Direction = readDirection(); return ( ); }); diff --git a/lib/platform-bible-react/src/components/shadcn-ui/select.tsx b/lib/platform-bible-react/src/components/shadcn-ui/select.tsx index df803ac947..8c383501bc 100644 --- a/lib/platform-bible-react/src/components/shadcn-ui/select.tsx +++ b/lib/platform-bible-react/src/components/shadcn-ui/select.tsx @@ -3,6 +3,7 @@ import * as SelectPrimitive from '@radix-ui/react-select'; import { Check, ChevronDown, ChevronUp } from 'lucide-react'; import { cn } from '@/utils/shadcn-ui.util'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; const Select = SelectPrimitive.Root; @@ -13,21 +14,25 @@ const SelectValue = SelectPrimitive.Value; const SelectTrigger = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - span]:tw-line-clamp-1', - className, - )} - {...props} - > - {children} - - - - -)); +>(({ className, children, ...props }, ref) => { + const dir: Direction = readDirection(); + return ( + span]:tw-line-clamp-1', + className, + )} + {...props} + dir={dir} + > + {children} + + + + + ); +}); SelectTrigger.displayName = SelectPrimitive.Trigger.displayName; const SelectScrollUpButton = React.forwardRef< @@ -61,33 +66,36 @@ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayNam const SelectContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, children, position = 'popper', ...props }, ref) => ( - - - - (({ className, children, position = 'popper', ...props }, ref) => { + const dir: Direction = readDirection(); + return ( + + - {children} - - - - -)); + + +
{children}
+
+ + + + ); +}); SelectContent.displayName = SelectPrimitive.Content.displayName; const SelectLabel = React.forwardRef< @@ -109,12 +117,12 @@ const SelectItem = React.forwardRef< - + diff --git a/lib/platform-bible-react/src/components/shadcn-ui/sidebar.tsx b/lib/platform-bible-react/src/components/shadcn-ui/sidebar.tsx index 2866245553..f2e0900689 100644 --- a/lib/platform-bible-react/src/components/shadcn-ui/sidebar.tsx +++ b/lib/platform-bible-react/src/components/shadcn-ui/sidebar.tsx @@ -14,6 +14,7 @@ import { TooltipTrigger, } from '@/components/shadcn-ui/tooltip'; import { cn } from '@/utils/shadcn-ui.util'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; /** * CUSTOM: Changes from the original code from Shadcn- Removed uses of useIsMobile, Sheet, and @@ -25,13 +26,15 @@ const SIDEBAR_WIDTH_ICON = '3rem'; // CUSTOM: Commented this out pending a discussion with UX about keyboard shortcuts // const SIDEBAR_KEYBOARD_SHORTCUT = 'b'; +type Side = 'primary' | 'secondary'; + type SidebarContextProps = { state: 'expanded' | 'collapsed'; open: boolean; setOpen: (open: boolean) => void; toggleSidebar: () => void; // CUSTOM: this was moved from Sidebar to SidebarProvider to also be able to flip the icon based on the side - side: 'left' | 'right'; + side: Side; }; const SidebarContext = React.createContext(undefined); @@ -51,7 +54,7 @@ const SidebarProvider = React.forwardRef< defaultOpen?: boolean; open?: boolean; onOpenChange?: (open: boolean) => void; - side?: 'left' | 'right'; + side?: Side; } >( ( @@ -62,7 +65,7 @@ const SidebarProvider = React.forwardRef< className, style, children, - side = 'left', + side = 'primary', ...props }, ref, @@ -106,15 +109,19 @@ const SidebarProvider = React.forwardRef< // This makes it easier to style the sidebar with Tailwind classes. const state = isOpen ? 'expanded' : 'collapsed'; + const dir: Direction = readDirection(); + const oppositeSide: Side = side === 'primary' ? 'secondary' : 'primary'; + const directionAwareSide = dir === 'ltr' ? side : oppositeSide; + const contextValue = React.useMemo( () => ({ state, open: isOpen, setOpen, toggleSidebar, - side, + side: directionAwareSide, }), - [state, isOpen, setOpen, toggleSidebar, side], + [state, isOpen, setOpen, toggleSidebar, directionAwareSide], ); return ( @@ -184,7 +191,7 @@ const Sidebar = React.forwardRef< className={cn( 'tw-relative tw-h-svh tw-w-[--sidebar-width] tw-bg-transparent tw-transition-[width] tw-duration-200 tw-ease-linear', 'group-data-[collapsible=offcanvas]:tw-w-0', - 'group-data-[side=right]:tw-rotate-180', + 'group-data-[side=secondary]:tw-rotate-180', variant === 'floating' || variant === 'inset' ? 'group-data-[collapsible=icon]:tw-w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]' : 'group-data-[collapsible=icon]:tw-w-[--sidebar-width-icon]', @@ -194,13 +201,13 @@ const Sidebar = React.forwardRef< className={cn( // CUSTOM: Switched tw-fixed to tw-absolute here to scope the sidebar inside of it's container 'tw-absolute tw-inset-y-0 tw-z-10 tw-hidden tw-h-svh tw-w-[--sidebar-width] tw-transition-[left,right,width] tw-duration-200 tw-ease-linear md:tw-flex', - context.side === 'left' + context.side === 'primary' ? 'tw-left-0 group-data-[collapsible=offcanvas]:tw-left-[calc(var(--sidebar-width)*-1)]' : 'tw-right-0 group-data-[collapsible=offcanvas]:tw-right-[calc(var(--sidebar-width)*-1)]', // Adjust the padding for floating and inset variants. variant === 'floating' || variant === 'inset' ? 'tw-p-2 group-data-[collapsible=icon]:tw-w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]' - : 'group-data-[collapsible=icon]:tw-w-[--sidebar-width-icon] group-data-[side=left]:tw-border-r group-data-[side=right]:tw-border-l', + : 'group-data-[collapsible=icon]:tw-w-[--sidebar-width-icon] group-data-[side=primary]:tw-border-r group-data-[side=secondary]:tw-border-l', className, )} {...props} @@ -236,7 +243,7 @@ const SidebarTrigger = React.forwardRef< }} {...props} > - {context.side === 'left' ? : } + {context.side === 'primary' ? : } Toggle Sidebar ); @@ -257,12 +264,12 @@ const SidebarRail = React.forwardRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - - - - -)); +>(({ className, ...props }, ref) => { + const dir: Direction = readDirection(); + return ( + + + + + + + ); +}); Slider.displayName = SliderPrimitive.Root.displayName; export { Slider }; diff --git a/lib/platform-bible-react/src/components/shadcn-ui/switch.tsx b/lib/platform-bible-react/src/components/shadcn-ui/switch.tsx index 2c21a5714d..5c9ab4074b 100644 --- a/lib/platform-bible-react/src/components/shadcn-ui/switch.tsx +++ b/lib/platform-bible-react/src/components/shadcn-ui/switch.tsx @@ -2,34 +2,38 @@ import * as SwitchPrimitives from '@radix-ui/react-switch'; import React from 'react'; import { cn } from '@/utils/shadcn-ui.util'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; const Switch = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef & { direction?: 'ltr' | 'rtl' } ->(({ className, direction, ...props }, ref) => ( - - +>(({ className, ...props }, ref) => { + const dir: Direction = readDirection(); + return ( + - -)); + {...props} + ref={ref} + > + + + ); +}); Switch.displayName = SwitchPrimitives.Root.displayName; export { Switch }; diff --git a/lib/platform-bible-react/src/components/shadcn-ui/tabs.tsx b/lib/platform-bible-react/src/components/shadcn-ui/tabs.tsx index b9d16ee167..bc1bdd9223 100644 --- a/lib/platform-bible-react/src/components/shadcn-ui/tabs.tsx +++ b/lib/platform-bible-react/src/components/shadcn-ui/tabs.tsx @@ -2,6 +2,7 @@ import React from 'react'; import * as TabsPrimitive from '@radix-ui/react-tabs'; import { cn } from '@/utils/shadcn-ui.util'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; export const Tabs = TabsPrimitive.Root; @@ -20,16 +21,20 @@ export type TabsContentProps = React.ComponentPropsWithoutRef, TabsListProps ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const dir: Direction = readDirection(); + return ( + + ); +}); TabsList.displayName = TabsPrimitive.List.displayName; export const TabsTrigger = React.forwardRef< diff --git a/lib/platform-bible-react/src/components/shadcn-ui/toggle-group.tsx b/lib/platform-bible-react/src/components/shadcn-ui/toggle-group.tsx index 6993ccbc98..754bdf378f 100644 --- a/lib/platform-bible-react/src/components/shadcn-ui/toggle-group.tsx +++ b/lib/platform-bible-react/src/components/shadcn-ui/toggle-group.tsx @@ -4,6 +4,7 @@ import { type VariantProps } from 'class-variance-authority'; import { cn } from '@/utils/shadcn-ui.util'; import { toggleVariants } from '@/components/shadcn-ui/toggle'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; const ToggleGroupContext = React.createContext>({ size: 'default', @@ -14,21 +15,25 @@ const ToggleGroup = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & VariantProps ->(({ className, variant, size, children, ...props }, ref) => ( - - (({ className, variant, size, children, ...props }, ref) => { + const dir: Direction = readDirection(); + return ( + - {children} - - -)); + + {children} + + + ); +}); ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName; diff --git a/lib/platform-bible-react/src/preview/app.component.tsx b/lib/platform-bible-react/src/preview/app.component.tsx index b79ddc6bab..e08b2596f8 100644 --- a/lib/platform-bible-react/src/preview/app.component.tsx +++ b/lib/platform-bible-react/src/preview/app.component.tsx @@ -1,18 +1,28 @@ -import { useState } from 'react'; +import { persistDirection } from '@/utils/dir-helper.util'; +import { useEffect, useState } from 'react'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '..'; import Compositions from './pages/components/advanced.component'; import Basics from './pages/components/basics.component'; import Guide from './pages/guide.component'; import Layouts from './pages/layouts.component'; import Playground from './pages/playground.component'; +import ContactButtons from './preview-components/contact-buttons.component'; import { DirToggle, Direction } from './preview-components/direction-toggle.component'; import { ThemeProvider } from './preview-components/theme-provider.component'; import { ThemeButton } from './preview-components/theme-toggle.component'; -import ContactButtons from './preview-components/contact-buttons.component'; + +const initialDirection: Direction = 'ltr'; function App() { - const [direction, setDirection] = useState('ltr'); - const changeDirectionHandler = (dir: Direction) => setDirection(dir); + const [direction, setDirection] = useState(initialDirection); + const changeDirectionHandler = (dir: Direction) => { + setDirection(dir); + persistDirection(dir); + }; + + useEffect(() => { + changeDirectionHandler(initialDirection); + }, []); return ( @@ -35,13 +45,13 @@ function App() { - + - + - + diff --git a/lib/platform-bible-react/src/preview/pages/components/advanced.component.tsx b/lib/platform-bible-react/src/preview/pages/components/advanced.component.tsx index 1d5ba0315b..e985f6bda1 100644 --- a/lib/platform-bible-react/src/preview/pages/components/advanced.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/advanced.component.tsx @@ -1,27 +1,26 @@ import BookChapterControl from '@/components/advanced/book-chapter-control/book-chapter-control.component'; import DataTable from '@/components/advanced/data-table/data-table.component'; +import ScrollGroupSelector from '@/components/advanced/scroll-group-selector.component'; +import TabNavigationContentSearch from '@/components/advanced/tab-navigation-content-search.component'; import { VerticalTabs, VerticalTabsContent, VerticalTabsList, VerticalTabsTrigger, } from '@/components/basics/tabs-vertical'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; import { defaultScrRef, ScrollGroupId } from 'platform-bible-utils'; import { useState } from 'react'; -import TabNavigationContentSearch from '@/components/advanced/tab-navigation-content-search.component'; -import ScrollGroupSelector from '@/components/advanced/scroll-group-selector.component'; -import MarketplaceButtonExamples from './advanced/marketplace-buttons.example.component'; -import ScriptureResultsViewerExample from './advanced/scripture-results-viewer.examples.component'; -import { columns, data } from './data-sources/data-table-content'; -import MarketplaceExamples from './advanced/marketplace.example.component'; -import InventoryExample from './advanced/inventory-example.component'; -import SettingsListExamples from './advanced/settings-list.examples.component'; import BookSelectorExample from './advanced/book-selector-example.component'; +import InventoryExample from './advanced/inventory-example.component'; import MarkdownRendererExample from './advanced/markdown-renderer-example.component'; +import MarketplaceButtonExamples from './advanced/marketplace-buttons.example.component'; +import MarketplaceExamples from './advanced/marketplace.example.component'; import MultiSelectComboBoxExample from './advanced/multi-select-combo-box-example'; +import ScriptureResultsViewerExample from './advanced/scripture-results-viewer.examples.component'; +import SettingsListExamples from './advanced/settings-list.examples.component'; +import { columns, data } from './data-sources/data-table-content'; -function Compositions({ direction }: HasDirection) { +function Compositions() { const [scrRef, setScrRef] = useState(defaultScrRef); const [scrollGroupId, setScrollGroupId] = useState(0); const [searchValue, setSearchValue] = useState(''); @@ -65,7 +64,7 @@ function Compositions({ direction }: HasDirection) {

A place for components that are composed from basic components

- + Book Chapter Control @@ -89,12 +88,12 @@ function Compositions({ direction }: HasDirection) { - +
{JSON.stringify(scrRef)}
- + @@ -102,7 +101,7 @@ function Compositions({ direction }: HasDirection) { - + Marketplace Buttons @@ -123,11 +122,11 @@ function Compositions({ direction }: HasDirection) { - + - + @@ -137,12 +136,11 @@ function Compositions({ direction }: HasDirection) { onSearch={handleSearchChange} searchPlaceholder="Search..." isSearchBarFullWidth - direction={direction} /> - + @@ -154,7 +152,6 @@ function Compositions({ direction }: HasDirection) { availableScrollGroupIds={[undefined, ...Array(5).keys()]} scrollGroupId={scrollGroupId} onChangeScrollGroupId={setScrollGroupId} - direction={direction} />
Scroll Group Id: {`${scrollGroupId}`}
diff --git a/lib/platform-bible-react/src/preview/pages/components/advanced/book-selector-example.component.tsx b/lib/platform-bible-react/src/preview/pages/components/advanced/book-selector-example.component.tsx index a0fc94610b..8a1e0fddc3 100644 --- a/lib/platform-bible-react/src/preview/pages/components/advanced/book-selector-example.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/advanced/book-selector-example.component.tsx @@ -1,5 +1,4 @@ import BookSelector, { BookSelectionMode } from '@/components/advanced/book-selector.component'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; import { Canon } from '@sillsdev/scripture'; import { useState } from 'react'; @@ -9,7 +8,7 @@ const localizedStrings = { '%webView_bookSelector_chooseBooks%': 'Choose Books', }; -function BookSelectorExample({ direction }: HasDirection) { +function BookSelectorExample() { const [startChapter, setStartChapter] = useState(0); const [endChapter, setEndChapter] = useState(0); const selectedBooksIds = [ @@ -37,7 +36,6 @@ function BookSelectorExample({ direction }: HasDirection) { onSelectBooks={handleSelectBooks} selectedBookIds={selectedBooksIds} localizedStrings={localizedStrings} - direction={direction} /> ); } diff --git a/lib/platform-bible-react/src/preview/pages/components/advanced/inventory-example.component.tsx b/lib/platform-bible-react/src/preview/pages/components/advanced/inventory-example.component.tsx index e3af2b42cd..14a01017af 100644 --- a/lib/platform-bible-react/src/preview/pages/components/advanced/inventory-example.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/advanced/inventory-example.component.tsx @@ -6,7 +6,6 @@ import { } from '@/components/advanced/inventory/inventory-columns'; import { InventoryTableData } from '@/components/advanced/inventory/inventory-utils'; import Inventory, { Scope } from '@/components/advanced/inventory/inventory.component'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; import { defaultScrRef } from 'platform-bible-utils'; import { useState } from 'react'; import scriptureSnippet from './scripture-snippet'; @@ -30,7 +29,6 @@ const createColumns = ( onApprovedItemsChange: (items: string[]) => void, unapprovedItems: string[], onUnapprovedItemsChange: (items: string[]) => void, - direction: 'ltr' | 'rtl', ): ColumnDef[] => [ inventoryItemColumn('Item'), inventoryCountColumn('Count'), @@ -40,11 +38,10 @@ const createColumns = ( onApprovedItemsChange, unapprovedItems, onUnapprovedItemsChange, - direction, ), ]; -function InventoryExample({ direction }: HasDirection) { +function InventoryExample() { const [scrRef, setScrRef] = useState(defaultScrRef); const [approvedItems, setApprovedItems] = useState(['well', 'he']); const [unapprovedItems, setUnapprovedItems] = useState(['for', 'of']); @@ -66,12 +63,10 @@ function InventoryExample({ direction }: HasDirection) { setApprovedItems, unapprovedItems, setUnapprovedItems, - direction, )} // Matches a sequence of letters surrounded by word boundaries followed by that exact same // sequence of letters surrounded by word boundaries extractItems={/\b(\p{L}+)\b(?=\s\b\1\b)/gu} - direction={direction} additionalItemsLabels={{ checkboxText: 'additional header', tableHeaders: ['additional header'], diff --git a/lib/platform-bible-react/src/preview/pages/components/advanced/multi-select-combo-box-example.tsx b/lib/platform-bible-react/src/preview/pages/components/advanced/multi-select-combo-box-example.tsx index 5c5c2f71d8..a640fcfae9 100644 --- a/lib/platform-bible-react/src/preview/pages/components/advanced/multi-select-combo-box-example.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/advanced/multi-select-combo-box-example.tsx @@ -1,5 +1,4 @@ import MultiSelectComboBox from '@/components/advanced/multi-select-combo-box'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; import { Blocks } from 'lucide-react'; import { useState } from 'react'; @@ -124,7 +123,7 @@ const resources = [ }, ]; -function MultiSelectComboBoxExample({ direction }: HasDirection) { +function MultiSelectComboBoxExample() { const [selectedTypes, setSelectedTypes] = useState(types.map((type) => type.value)); const getOptionsCount = (option: MultiSelectComboBoxEntry): number => { @@ -146,7 +145,6 @@ function MultiSelectComboBoxExample({ direction }: HasDirection) { : `${selectedTypes.length} type${selectedTypes.length > 1 ? 's' : ''}` } icon={} - direction={direction} />
diff --git a/lib/platform-bible-react/src/preview/pages/components/advanced/scripture-results-viewer.examples.component.tsx b/lib/platform-bible-react/src/preview/pages/components/advanced/scripture-results-viewer.examples.component.tsx index f87204df9e..8ddc0d24e7 100644 --- a/lib/platform-bible-react/src/preview/pages/components/advanced/scripture-results-viewer.examples.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/advanced/scripture-results-viewer.examples.component.tsx @@ -1,10 +1,9 @@ import ScriptureResultsViewer from '@/components/advanced/scripture-results-viewer/scripture-results-viewer.component'; import { Button } from '@/components/shadcn-ui/button'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; import { useState } from 'react'; import generateRandomCheckingData from '../data-sources/generate-random-checking-data'; -export default function ScriptureResultsViewerExample({ direction }: HasDirection) { +export default function ScriptureResultsViewerExample() { const checks = [ { id: 'preview.repeatedWords', @@ -80,7 +79,6 @@ export default function ScriptureResultsViewerExample({ direction }: HasDirectio scriptureReferenceColumnName="Scripture Reference" typeColumnName="Check Type" detailsColumnName="Error Details" - direction={direction} />
); diff --git a/lib/platform-bible-react/src/preview/pages/components/basics.component.tsx b/lib/platform-bible-react/src/preview/pages/components/basics.component.tsx index e7621e36b1..2778c29000 100644 --- a/lib/platform-bible-react/src/preview/pages/components/basics.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/basics.component.tsx @@ -4,7 +4,6 @@ import { VerticalTabsList, VerticalTabsTrigger, } from '@/components/basics/tabs-vertical'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; import ExampleAlerts from './basics/alert.examples.component'; import BadgeExamples from './basics/badge.examples.component'; import ButtonExamples from './basics/button.examples.component'; @@ -13,6 +12,7 @@ import ChapterRangeSelectorExample from './basics/chapter-range-example.componen import CheckboxExamples from './basics/checkbox.examples.component'; import ChecklistExamples from './basics/checklist.examples.component'; import ComboBoxExamples from './basics/combo-box.examples.component'; +import DialogExamples from './basics/dialog.examples.component'; import DropdownExamples from './basics/dropdown.examples.component'; import InputExamples from './basics/input.examples.component'; import RadioGroupExamples from './basics/radio-group.examples'; @@ -26,13 +26,12 @@ import SwitchExamples from './basics/switch.examples.component'; import TabExamples from './basics/tab.examples.component'; import TableExamples from './basics/table.examples.component'; import ToggleGroupExamples from './basics/toggle-group.examples.component'; -import DialogExamples from './basics/dialog.examples.component'; -function Basics({ direction }: HasDirection) { +function Basics() { return (

A place for the most simple components

- + Alert Badge @@ -73,11 +72,11 @@ function Basics({ direction }: HasDirection) { - + - + @@ -89,11 +88,11 @@ function Basics({ direction }: HasDirection) { - + - + @@ -101,25 +100,25 @@ function Basics({ direction }: HasDirection) { - + - + - +
- +
- + @@ -127,19 +126,19 @@ function Basics({ direction }: HasDirection) { - + - + - + - + @@ -147,7 +146,7 @@ function Basics({ direction }: HasDirection) { - +
diff --git a/lib/platform-bible-react/src/preview/pages/components/basics/card.examples.component.tsx b/lib/platform-bible-react/src/preview/pages/components/basics/card.examples.component.tsx index 3dcad382de..04f795a07a 100644 --- a/lib/platform-bible-react/src/preview/pages/components/basics/card.examples.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/basics/card.examples.component.tsx @@ -10,11 +10,10 @@ import { import { Input } from '@/components/shadcn-ui/input'; import { Label } from '@/components/shadcn-ui/label'; import { Switch } from '@/components/shadcn-ui/switch'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; import { BellRing, Check } from 'lucide-react'; import SelectExamples from './select.examples.component'; -export default function CardExamples({ direction }: HasDirection) { +export default function CardExamples() { const cardContent = (
@@ -76,7 +75,7 @@ export default function CardExamples({ direction }: HasDirection) {
- +
diff --git a/lib/platform-bible-react/src/preview/pages/components/basics/chapter-range-example.component.tsx b/lib/platform-bible-react/src/preview/pages/components/basics/chapter-range-example.component.tsx index b405412a5f..b45dfdc8d2 100644 --- a/lib/platform-bible-react/src/preview/pages/components/basics/chapter-range-example.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/basics/chapter-range-example.component.tsx @@ -1,9 +1,8 @@ import ChapterRangeSelector from '@/components/basics/chapter-range-selector.component'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; import { getChaptersForBook } from 'platform-bible-utils'; import { useState } from 'react'; -export default function ChapterRangeSelectorExample({ direction }: HasDirection) { +export default function ChapterRangeSelectorExample() { const chapterCount = getChaptersForBook(1); const [startChapter, setStartChapter] = useState(1); const [endChapter, setEndChapter] = useState(chapterCount); @@ -22,7 +21,6 @@ export default function ChapterRangeSelectorExample({ direction }: HasDirection) handleSelectStartChapter={handleSelectStart} handleSelectEndChapter={handleSelectEnd} chapterCount={chapterCount} - direction={direction} /> ); } diff --git a/lib/platform-bible-react/src/preview/pages/components/basics/combo-box.examples.component.tsx b/lib/platform-bible-react/src/preview/pages/components/basics/combo-box.examples.component.tsx index a5aad0ecb5..70ccc5cb97 100644 --- a/lib/platform-bible-react/src/preview/pages/components/basics/combo-box.examples.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/basics/combo-box.examples.component.tsx @@ -1,9 +1,8 @@ import ComboBox from '@/components/basics/combo-box.component'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; import { BookOpen } from 'lucide-react'; import { useState } from 'react'; -export default function ComboBoxExamples({ direction }: HasDirection) { +export default function ComboBoxExamples() { const [comboBox1Value, setComboBox1Value] = useState(undefined); const [comboBox2Value, setComboBox2Value] = useState(undefined); const [comboBox3Value, setComboBox3Value] = useState(undefined); @@ -14,7 +13,6 @@ export default function ComboBoxExamples({ direction }: HasDirection) {

Default Combobox

Combobox with long text for options will truncate

An icon can be shown on the trigger button

Alignment of dropdown menu can be controlled

- + Clear filters Clear filters to show all results? diff --git a/lib/platform-bible-react/src/preview/pages/components/basics/dropdown.examples.component.tsx b/lib/platform-bible-react/src/preview/pages/components/basics/dropdown.examples.component.tsx index 70a61bde24..c3b3bd0067 100644 --- a/lib/platform-bible-react/src/preview/pages/components/basics/dropdown.examples.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/basics/dropdown.examples.component.tsx @@ -1,20 +1,23 @@ import { Button } from '@/components/shadcn-ui/button'; import { DropdownMenu, + DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, } from '@/components/shadcn-ui/dropdown-menu'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; + import { ChevronDown } from 'lucide-react'; -export default function DropdownExamples({ direction }: HasDirection) { +export default function DropdownExamples() { return ( - + @@ -24,7 +25,7 @@ export default function TabExamples({ direction }: HasDirection) { {/* intentionally left out 3 to see the effect */}
- + @@ -37,7 +38,7 @@ export default function TabExamples({ direction }: HasDirection) {
Tab 2 Content: Another set of vertical tabs without a default value - + Tab 2-1 Tab 2-2 diff --git a/lib/platform-bible-react/src/preview/pages/components/basics/toggle-group.examples.component.tsx b/lib/platform-bible-react/src/preview/pages/components/basics/toggle-group.examples.component.tsx index 5dd83f26ba..fed9de89b0 100644 --- a/lib/platform-bible-react/src/preview/pages/components/basics/toggle-group.examples.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/components/basics/toggle-group.examples.component.tsx @@ -1,15 +1,14 @@ import { ToggleGroup, ToggleGroupItem } from '@/components/shadcn-ui/toggle-group'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; -export default function ToggleGroupExamples({ direction }: HasDirection) { +export default function ToggleGroupExamples() { return (
- + A B C - + A B C diff --git a/lib/platform-bible-react/src/preview/pages/guide.component.tsx b/lib/platform-bible-react/src/preview/pages/guide.component.tsx index dd67a5c33e..a5e165f4e6 100644 --- a/lib/platform-bible-react/src/preview/pages/guide.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/guide.component.tsx @@ -17,7 +17,7 @@ function Guide({ direction, onChangeDirection: setDirection }: DirectionProps) {

A place to look up and learn about some concepts

- + How to use Direction diff --git a/lib/platform-bible-react/src/preview/pages/layouts.component.tsx b/lib/platform-bible-react/src/preview/pages/layouts.component.tsx index 7c2b4c068d..2569c5f997 100644 --- a/lib/platform-bible-react/src/preview/pages/layouts.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/layouts.component.tsx @@ -4,18 +4,18 @@ import { VerticalTabsList, VerticalTabsTrigger, } from '@/components/basics/tabs-vertical'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; + import WindowOrTabExample from './layouts/window.layout.component'; import Dashboard5Examples from './layouts/dashboard5.layout.component'; import ToolbarExamples from './layouts/toolbar.layout.component'; import DialogExamples from './layouts/dialog.layout.component'; import GetResourcesExample from './layouts/resource-manager.layout.component'; -function Layouts({ direction }: HasDirection) { +function Layouts() { return (

A place to add examples for layouts

- + Window or Tab MUI Toolbar @@ -27,25 +27,25 @@ function Layouts({ direction }: HasDirection) {
- - + +
- +
- + TODO - +
- +
diff --git a/lib/platform-bible-react/src/preview/pages/layouts/dashboard5.layout.component.tsx b/lib/platform-bible-react/src/preview/pages/layouts/dashboard5.layout.component.tsx index 9e3a4964d6..497c3af730 100644 --- a/lib/platform-bible-react/src/preview/pages/layouts/dashboard5.layout.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/layouts/dashboard5.layout.component.tsx @@ -50,10 +50,11 @@ import { } from '@/components/shadcn-ui/table'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/shadcn-ui/tabs'; import { useState } from 'react'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; +import { Direction, readDirection } from '@/utils/dir-helper.util'; -export default function Dashboard5Examples({ direction }: HasDirection) { +export default function Dashboard5Examples() { const [progress, setProgress] = useState([25]); + const dir: Direction = readDirection(); return (
-
+
- + - + Edit Export diff --git a/lib/platform-bible-react/src/preview/pages/layouts/resource-manager.layout.component.tsx b/lib/platform-bible-react/src/preview/pages/layouts/resource-manager.layout.component.tsx index ca83e220c2..a4ad822d1e 100644 --- a/lib/platform-bible-react/src/preview/pages/layouts/resource-manager.layout.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/layouts/resource-manager.layout.component.tsx @@ -23,7 +23,6 @@ import { import { cn } from '@/utils/shadcn-ui.util'; import { DialogTitle } from '@radix-ui/react-dialog'; import MultiSelectComboBox from '@/components/advanced/multi-select-combo-box'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; type MultiSelectComboBoxEntry = { value: string; @@ -165,7 +164,7 @@ const tableData = [ }, ]; -export default function GetResourcesExample({ direction }: HasDirection) { +export default function GetResourcesExample() { const [selectedTypes, setSelectedTypes] = React.useState( types.map((type) => type.value), ); @@ -242,7 +241,6 @@ export default function GetResourcesExample({ direction }: HasDirection) { onSearch={setSearchQuery} placeholder="Search by name, language, type..." className={cn('tw-px-8', searchQuery && 'tw-border-primary')} - direction={direction} /> 1 ? 's' : ''}` } icon={} - direction={direction} /> } - direction={direction} />
diff --git a/lib/platform-bible-react/src/preview/pages/layouts/toolbar.layout.component.tsx b/lib/platform-bible-react/src/preview/pages/layouts/toolbar.layout.component.tsx index 6c9fcdd961..85d501d85f 100644 --- a/lib/platform-bible-react/src/preview/pages/layouts/toolbar.layout.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/layouts/toolbar.layout.component.tsx @@ -1,11 +1,11 @@ import BookChapterControl from '@/components/advanced/book-chapter-control/book-chapter-control.component'; import { MultiColumnMenuProvider } from '@/components/mui/hamburger-menu-button.component'; import Toolbar from '@/components/mui/toolbar.component'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; + import { defaultScrRef, Localized, MultiColumnMenu } from 'platform-bible-utils'; import { useState } from 'react'; -export default function ToolbarExamples({ direction }: HasDirection) { +export default function ToolbarExamples() { const [scrRef] = useState(defaultScrRef); const menu: MultiColumnMenu = { columns: {}, groups: {}, items: [] }; const menuProvider: MultiColumnMenuProvider = () => @@ -15,11 +15,11 @@ export default function ToolbarExamples({ direction }: HasDirection) { return (
{}}> - {}} direction={direction} /> + {}} /> {}}> - {}} direction={direction} /> + {}} />
); diff --git a/lib/platform-bible-react/src/preview/pages/layouts/window.layout.component.tsx b/lib/platform-bible-react/src/preview/pages/layouts/window.layout.component.tsx index 8489341a73..627e04b36b 100644 --- a/lib/platform-bible-react/src/preview/pages/layouts/window.layout.component.tsx +++ b/lib/platform-bible-react/src/preview/pages/layouts/window.layout.component.tsx @@ -11,7 +11,7 @@ import { DropdownMenuTrigger, } from '@/components/shadcn-ui/dropdown-menu'; import { Tabs, TabsList, TabsTrigger } from '@/components/shadcn-ui/tabs'; -import { HasDirection } from '@/preview/preview-components/direction-toggle.component'; + import { defaultScrRef } from 'platform-bible-utils'; import { useState } from 'react'; @@ -19,7 +19,7 @@ export type HasIsFocused = { isFocused?: boolean; }; -export default function WindowOrTabExample({ direction, isFocused }: HasDirection & HasIsFocused) { +export default function WindowOrTabExample({ isFocused }: HasIsFocused) { const [scrRef, setScrRef] = useState(defaultScrRef); const highlightClassName = isFocused ? 'tw-bg-primary tw-text-primary-foreground' @@ -28,17 +28,17 @@ export default function WindowOrTabExample({ direction, isFocused }: HasDirectio
- +
- + A B - + @@ -74,7 +74,7 @@ export default function WindowOrTabExample({ direction, isFocused }: HasDirectio }} > Scroll with - + A diff --git a/lib/platform-bible-react/src/utils/dir-helper.util.ts b/lib/platform-bible-react/src/utils/dir-helper.util.ts new file mode 100644 index 0000000000..e1488c5d5c --- /dev/null +++ b/lib/platform-bible-react/src/utils/dir-helper.util.ts @@ -0,0 +1,18 @@ +/** Text and layout direction */ +export type Direction = 'rtl' | 'ltr'; + +const STORAGE_KEY: string = 'layoutDirection'; + +/** Read layout direction from localStorage or return 'ltr' */ +export function readDirection(): Direction { + const retrieved = localStorage.getItem(STORAGE_KEY); + if (retrieved === 'rtl') { + return retrieved; + } + return 'ltr'; +} + +/** Write layout direction to localStorage */ +export function persistDirection(dir: Direction): void { + localStorage.setItem(STORAGE_KEY, dir); +}