@faststore/ui 2.0.37-alpha.0 → 2.0.41-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/index.d.ts +0 -4
  3. package/dist/index.js +0 -2
  4. package/dist/index.js.map +1 -1
  5. package/package.json +2 -2
  6. package/src/base/tokens.scss +1 -1
  7. package/src/components/molecules/Accordion/styles.scss +70 -0
  8. package/src/components/molecules/Dropdown/styles.scss +93 -0
  9. package/src/index.ts +0 -26
  10. package/src/styles/components.scss +2 -0
  11. package/dist/components/molecules/Accordion/Accordion.d.ts +0 -26
  12. package/dist/components/molecules/Accordion/Accordion.js +0 -21
  13. package/dist/components/molecules/Accordion/Accordion.js.map +0 -1
  14. package/dist/components/molecules/Accordion/AccordionButton.d.ts +0 -10
  15. package/dist/components/molecules/Accordion/AccordionButton.js +0 -37
  16. package/dist/components/molecules/Accordion/AccordionButton.js.map +0 -1
  17. package/dist/components/molecules/Accordion/AccordionItem.d.ts +0 -31
  18. package/dist/components/molecules/Accordion/AccordionItem.js +0 -22
  19. package/dist/components/molecules/Accordion/AccordionItem.js.map +0 -1
  20. package/dist/components/molecules/Accordion/AccordionPanel.d.ts +0 -10
  21. package/dist/components/molecules/Accordion/AccordionPanel.js +0 -10
  22. package/dist/components/molecules/Accordion/AccordionPanel.js.map +0 -1
  23. package/dist/components/molecules/Accordion/index.d.ts +0 -8
  24. package/dist/components/molecules/Accordion/index.js +0 -5
  25. package/dist/components/molecules/Accordion/index.js.map +0 -1
  26. package/dist/components/molecules/Dropdown/Dropdown.d.ts +0 -9
  27. package/dist/components/molecules/Dropdown/Dropdown.js +0 -67
  28. package/dist/components/molecules/Dropdown/Dropdown.js.map +0 -1
  29. package/dist/components/molecules/Dropdown/DropdownButton.d.ts +0 -10
  30. package/dist/components/molecules/Dropdown/DropdownButton.js +0 -11
  31. package/dist/components/molecules/Dropdown/DropdownButton.js.map +0 -1
  32. package/dist/components/molecules/Dropdown/DropdownItem.d.ts +0 -10
  33. package/dist/components/molecules/Dropdown/DropdownItem.js +0 -26
  34. package/dist/components/molecules/Dropdown/DropdownItem.js.map +0 -1
  35. package/dist/components/molecules/Dropdown/DropdownMenu.d.ts +0 -22
  36. package/dist/components/molecules/Dropdown/DropdownMenu.js +0 -65
  37. package/dist/components/molecules/Dropdown/DropdownMenu.js.map +0 -1
  38. package/dist/components/molecules/Dropdown/contexts/DropdownContext.d.ts +0 -41
  39. package/dist/components/molecules/Dropdown/contexts/DropdownContext.js +0 -11
  40. package/dist/components/molecules/Dropdown/contexts/DropdownContext.js.map +0 -1
  41. package/dist/components/molecules/Dropdown/hooks/useDropdown.d.ts +0 -6
  42. package/dist/components/molecules/Dropdown/hooks/useDropdown.js +0 -14
  43. package/dist/components/molecules/Dropdown/hooks/useDropdown.js.map +0 -1
  44. package/dist/components/molecules/Dropdown/hooks/useDropdownPosition.d.ts +0 -8
  45. package/dist/components/molecules/Dropdown/hooks/useDropdownPosition.js +0 -25
  46. package/dist/components/molecules/Dropdown/hooks/useDropdownPosition.js.map +0 -1
  47. package/dist/components/molecules/Dropdown/index.d.ts +0 -8
  48. package/dist/components/molecules/Dropdown/index.js +0 -5
  49. package/dist/components/molecules/Dropdown/index.js.map +0 -1
  50. package/src/components/molecules/Accordion/Accordion.tsx +0 -76
  51. package/src/components/molecules/Accordion/AccordionButton.tsx +0 -81
  52. package/src/components/molecules/Accordion/AccordionItem.tsx +0 -92
  53. package/src/components/molecules/Accordion/AccordionPanel.tsx +0 -40
  54. package/src/components/molecules/Accordion/index.ts +0 -11
  55. package/src/components/molecules/Dropdown/Dropdown.tsx +0 -102
  56. package/src/components/molecules/Dropdown/DropdownButton.tsx +0 -42
  57. package/src/components/molecules/Dropdown/DropdownItem.tsx +0 -69
  58. package/src/components/molecules/Dropdown/DropdownMenu.tsx +0 -139
  59. package/src/components/molecules/Dropdown/contexts/DropdownContext.ts +0 -53
  60. package/src/components/molecules/Dropdown/hooks/useDropdown.ts +0 -18
  61. package/src/components/molecules/Dropdown/hooks/useDropdownPosition.ts +0 -33
  62. package/src/components/molecules/Dropdown/index.ts +0 -11
@@ -1,102 +0,0 @@
1
- import type { ReactNode } from 'react'
2
- import React, { useRef, useMemo, useState, useEffect, useCallback } from 'react'
3
-
4
- import DropdownContext from './contexts/DropdownContext'
5
-
6
- export type DropdownProps = {
7
- children: ReactNode
8
- onDismiss?(): void
9
- isOpen?: boolean
10
- id?: string
11
- }
12
-
13
- const Dropdown = ({
14
- children,
15
- isOpen: isOpenDefault = false,
16
- onDismiss,
17
- id = 'store-dropdown',
18
- }: DropdownProps) => {
19
- const [isOpen, setIsOpen] = useState(isOpenDefault)
20
- const dropdownItemsRef = useRef<HTMLButtonElement[]>([])
21
- const selectedDropdownItemIndexRef = useRef(0)
22
- const dropdownButtonRef = useRef<HTMLButtonElement>(null)
23
-
24
- const close = useCallback(() => {
25
- setIsOpen(false)
26
- onDismiss?.()
27
- dropdownButtonRef.current?.focus()
28
- }, [onDismiss])
29
-
30
- const open = () => {
31
- setIsOpen(true)
32
- }
33
-
34
- const toggle = useCallback(() => {
35
- setIsOpen((old) => {
36
- if (old) {
37
- onDismiss?.()
38
- dropdownButtonRef.current?.focus()
39
- }
40
-
41
- return !old
42
- })
43
- }, [onDismiss])
44
-
45
- useEffect(() => {
46
- setIsOpen(isOpenDefault)
47
- }, [isOpenDefault])
48
-
49
- useEffect(() => {
50
- isOpen && dropdownItemsRef?.current[0]?.focus()
51
- }, [isOpen])
52
-
53
- useEffect(() => {
54
- let firstClick = true
55
-
56
- const event = (e: MouseEvent) => {
57
- const someItemWasClicked = dropdownItemsRef?.current.some(
58
- (item) => e.target === item
59
- )
60
-
61
- if (firstClick) {
62
- firstClick = false
63
-
64
- return
65
- }
66
-
67
- !someItemWasClicked && close()
68
- }
69
-
70
- if (isOpen) {
71
- document.addEventListener('click', event)
72
- } else {
73
- document.removeEventListener('click', event)
74
- }
75
-
76
- return () => {
77
- document.removeEventListener('click', event)
78
- }
79
- }, [close, isOpen])
80
-
81
- const value = useMemo(() => {
82
- return {
83
- isOpen,
84
- close,
85
- open,
86
- toggle,
87
- dropdownButtonRef,
88
- onDismiss,
89
- selectedDropdownItemIndexRef,
90
- dropdownItemsRef,
91
- id,
92
- }
93
- }, [close, id, isOpen, onDismiss, toggle])
94
-
95
- return (
96
- <DropdownContext.Provider value={value}>
97
- {children}
98
- </DropdownContext.Provider>
99
- )
100
- }
101
-
102
- export default Dropdown
@@ -1,42 +0,0 @@
1
- import type { ButtonHTMLAttributes } from 'react'
2
- import React, { forwardRef, useImperativeHandle } from 'react'
3
-
4
- import { useDropdown } from './hooks/useDropdown'
5
-
6
- export interface DropdownButtonProps
7
- extends ButtonHTMLAttributes<HTMLButtonElement> {
8
- /**
9
- * ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
10
- */
11
- testId?: string
12
- }
13
-
14
- const DropdownButton = forwardRef<HTMLButtonElement, DropdownButtonProps>(
15
- function Button(
16
- { children, testId = 'store-dropdown-button', ...otherProps },
17
- ref
18
- ) {
19
- const { toggle, dropdownButtonRef, isOpen, id } = useDropdown()
20
-
21
- useImperativeHandle(ref, () => dropdownButtonRef!.current!, [
22
- dropdownButtonRef,
23
- ])
24
-
25
- return (
26
- <button
27
- data-fs-dropdown-button
28
- onClick={toggle}
29
- data-testid={testId}
30
- ref={dropdownButtonRef}
31
- aria-expanded={isOpen}
32
- aria-haspopup="menu"
33
- aria-controls={id}
34
- {...otherProps}
35
- >
36
- {children}
37
- </button>
38
- )
39
- }
40
- )
41
-
42
- export default DropdownButton
@@ -1,69 +0,0 @@
1
- import type { ButtonHTMLAttributes } from 'react'
2
- import React, { useImperativeHandle, forwardRef, useRef, useState } from 'react'
3
-
4
- import { useDropdown } from './hooks/useDropdown'
5
-
6
- export interface DropdownItemProps
7
- extends ButtonHTMLAttributes<HTMLButtonElement> {
8
- /**
9
- * ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
10
- */
11
- testId?: string
12
- }
13
-
14
- const DropdownItem = forwardRef<HTMLButtonElement, DropdownItemProps>(
15
- function Button(
16
- { children, onClick, testId = 'store-dropdown-item', ...otherProps },
17
- ref
18
- ) {
19
- const { dropdownItemsRef, selectedDropdownItemIndexRef, close } =
20
- useDropdown()
21
-
22
- const [dropdownItemIndex, setDropdownItemIndex] = useState(0)
23
- const dropdownItemRef = useRef<HTMLButtonElement>()
24
-
25
- const addToRefs = (el: HTMLButtonElement) => {
26
- if (el && !dropdownItemsRef?.current.includes(el)) {
27
- dropdownItemsRef?.current.push(el)
28
- setDropdownItemIndex(
29
- dropdownItemsRef?.current.findIndex((element) => element === el) ?? 0
30
- )
31
- }
32
-
33
- dropdownItemRef.current = el
34
- }
35
-
36
- const onFocusItem = () => {
37
- selectedDropdownItemIndexRef!.current = dropdownItemIndex
38
- dropdownItemsRef?.current[selectedDropdownItemIndexRef!.current]?.focus()
39
- }
40
-
41
- const handleOnClickItem = (
42
- event: React.MouseEvent<HTMLButtonElement, MouseEvent>
43
- ) => {
44
- onClick?.(event)
45
- close?.()
46
- }
47
-
48
- useImperativeHandle(ref, () => dropdownItemRef.current!, [])
49
-
50
- return (
51
- <button
52
- data-fs-dropdown-item
53
- data-testid={testId}
54
- ref={addToRefs}
55
- onFocus={onFocusItem}
56
- onMouseEnter={onFocusItem}
57
- onClick={handleOnClickItem}
58
- role="menuitem"
59
- tabIndex={-1}
60
- data-index={dropdownItemIndex}
61
- {...otherProps}
62
- >
63
- {children}
64
- </button>
65
- )
66
- }
67
- )
68
-
69
- export default DropdownItem
@@ -1,139 +0,0 @@
1
- import type {
2
- AriaAttributes,
3
- KeyboardEvent,
4
- PropsWithChildren,
5
- MouseEvent,
6
- ReactNode,
7
- } from 'react'
8
- import React from 'react'
9
- import { createPortal } from 'react-dom'
10
-
11
- import type { ModalContentProps } from '../Modal/ModalContent'
12
- import { useDropdown } from './hooks/useDropdown'
13
- import { useDropdownPosition } from './hooks/useDropdownPosition'
14
-
15
- export interface DropdownMenuProps extends ModalContentProps {
16
- /**
17
- * ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
18
- */
19
- testId?: string
20
- /**
21
- * Identifies the element (or elements) that labels the current element.
22
- * @see aria-labelledby https://www.w3.org/TR/wai-aria-1.1/#aria-labelledby
23
- */
24
- 'aria-labelledby'?: AriaAttributes['aria-label']
25
-
26
- /**
27
- * This function is called whenever the user hits "Escape" or clicks outside
28
- * the dialog.
29
- */
30
- onDismiss?: (event: MouseEvent | KeyboardEvent) => void
31
-
32
- children: ReactNode[] | ReactNode
33
- }
34
-
35
- /*
36
- * This component is based on @reach/dialog.
37
- * https://github.com/reach/reach-ui/blob/main/packages/dialog/src/index.tsx
38
- * https://reach.tech/dialog
39
- */
40
-
41
- const DropdownMenu = ({
42
- children,
43
- testId = 'store-dropdown-menu',
44
- style,
45
- ...otherProps
46
- }: PropsWithChildren<DropdownMenuProps>) => {
47
- const { isOpen, close, dropdownItemsRef, selectedDropdownItemIndexRef, id } =
48
- useDropdown()
49
-
50
- const dropdownPosition = useDropdownPosition()
51
-
52
- const childrenLength = React.Children.toArray(children).length
53
-
54
- const handleDownPress = () => {
55
- if (selectedDropdownItemIndexRef!.current < childrenLength - 1) {
56
- selectedDropdownItemIndexRef!.current++
57
- } else {
58
- selectedDropdownItemIndexRef!.current = 0
59
- }
60
-
61
- dropdownItemsRef?.current[selectedDropdownItemIndexRef!.current]?.focus()
62
- }
63
-
64
- const handleUpPress = () => {
65
- if (selectedDropdownItemIndexRef!.current > 0) {
66
- selectedDropdownItemIndexRef!.current--
67
- } else {
68
- selectedDropdownItemIndexRef!.current = childrenLength - 1
69
- }
70
-
71
- dropdownItemsRef?.current[selectedDropdownItemIndexRef!.current]?.focus()
72
- }
73
-
74
- const handleHomePress = () => {
75
- selectedDropdownItemIndexRef!.current = 0
76
- dropdownItemsRef?.current[selectedDropdownItemIndexRef!.current]?.focus()
77
- }
78
-
79
- const handleEndPress = () => {
80
- selectedDropdownItemIndexRef!.current = childrenLength - 1
81
- dropdownItemsRef?.current[selectedDropdownItemIndexRef!.current]?.focus()
82
- }
83
-
84
- const handleEscapePress = () => {
85
- close?.()
86
- }
87
-
88
- const handleBackdropKeyDown = (event: KeyboardEvent) => {
89
- if (event.defaultPrevented || event.key === 'Enter') {
90
- return
91
- }
92
-
93
- event.preventDefault()
94
-
95
- event.key === 'Escape' && handleEscapePress()
96
-
97
- event.key === 'ArrowDown' && handleDownPress()
98
-
99
- event.key === 'ArrowUp' && handleUpPress()
100
-
101
- event.key === 'Home' && handleHomePress()
102
-
103
- event.key === 'End' && handleEndPress()
104
-
105
- event.stopPropagation()
106
- }
107
-
108
- const clearChildrenReferences = () => {
109
- dropdownItemsRef!.current = []
110
-
111
- return null
112
- }
113
-
114
- return isOpen
115
- ? createPortal(
116
- <div
117
- role="presentation"
118
- data-fs-dropdown-overlay
119
- onKeyDown={handleBackdropKeyDown}
120
- data-testid={`${testId}-overlay`}
121
- >
122
- <div
123
- role="menu"
124
- aria-orientation="vertical"
125
- data-fs-dropdown-menu
126
- data-testid={testId}
127
- style={{ ...dropdownPosition, ...style }}
128
- id={id}
129
- {...otherProps}
130
- >
131
- {children}
132
- </div>
133
- </div>,
134
- document.body
135
- )
136
- : clearChildrenReferences()
137
- }
138
-
139
- export default DropdownMenu
@@ -1,53 +0,0 @@
1
- import { createContext } from 'react'
2
-
3
- export type DropdownContextState = {
4
- /**
5
- * Control de Dropdown state as Opened (true) or Closed (false).
6
- */
7
- isOpen: boolean
8
- /**
9
- * Reference to DropdownButton, used to calculate a position for the DropdownMenu.
10
- */
11
- dropdownButtonRef: React.RefObject<HTMLButtonElement> | null
12
- /**
13
- * Reference to a selected DropdownItem, used to manipulate focus.
14
- */
15
- selectedDropdownItemIndexRef: React.MutableRefObject<number> | null
16
- /**
17
- * Array of References to dropdownItems in a DropdownMenu.
18
- */
19
- dropdownItemsRef: React.MutableRefObject<HTMLButtonElement[]> | null
20
- /**
21
- * Close DropdownMenu event inherited from Modal.
22
- */
23
- onDismiss?(): void
24
- /**
25
- * Function responsible for close the DropdownMenu in this context.
26
- */
27
- close?(): void
28
- /**
29
- * Function responsible for open the DropdownMenu in this context.
30
- */
31
- open?(): void
32
- /**
33
- * Function responsible for switch the the DropdownMenu state in this context.
34
- */
35
- toggle?(): void
36
-
37
- /**
38
- * Identifier to be used in aria-controls
39
- */
40
- id: string
41
- }
42
-
43
- const defaultState: DropdownContextState = {
44
- isOpen: false,
45
- dropdownButtonRef: null,
46
- selectedDropdownItemIndexRef: null,
47
- dropdownItemsRef: null,
48
- id: 'store-dropdown',
49
- }
50
-
51
- const DropdownContext = createContext<DropdownContextState>(defaultState)
52
-
53
- export default DropdownContext
@@ -1,18 +0,0 @@
1
- import { useContext } from 'react'
2
-
3
- import type { DropdownContextState } from '../contexts/DropdownContext'
4
- import DropdownContext from '../contexts/DropdownContext'
5
-
6
- /**
7
- * Hook to use the Dropdown context.
8
- * @returns Dropdown context.
9
- */
10
- export const useDropdown = () => {
11
- const context = useContext<DropdownContextState>(DropdownContext)
12
-
13
- if (context === undefined) {
14
- throw new Error('Do not use useDropdown hook outside the Dropdown context.')
15
- }
16
-
17
- return context
18
- }
@@ -1,33 +0,0 @@
1
- import { useDropdown } from './useDropdown'
2
-
3
- type DropdownPosition = Pick<React.CSSProperties, 'position' | 'top' | 'left'>
4
-
5
- /**
6
- * Hook used to find the DropdownMenu position in relation to DropdownButton
7
- * @returns Style with positions.
8
- */
9
- export const useDropdownPosition = (): DropdownPosition => {
10
- const { dropdownButtonRef } = useDropdown()
11
-
12
- // Necessary to use this component in SSR
13
- const isBrowser = typeof window !== 'undefined'
14
-
15
- const buttonRect = dropdownButtonRef?.current?.getBoundingClientRect()
16
- const topLevel = buttonRect?.top ?? 0
17
- const topOffset = buttonRect?.height ?? 0
18
- const leftLevel = buttonRect?.left ?? 0
19
-
20
- // The scroll properties fix the position of DropdownMenu when the scroll is activated.
21
- const scrollTop = isBrowser ? document?.documentElement?.scrollTop : 0
22
- const scrollLeft = isBrowser ? document?.documentElement?.scrollLeft : 0
23
-
24
- const topPosition = topLevel + topOffset + scrollTop
25
-
26
- const leftPosition = leftLevel + scrollLeft
27
-
28
- return {
29
- position: 'absolute',
30
- top: topPosition,
31
- left: leftPosition,
32
- }
33
- }
@@ -1,11 +0,0 @@
1
- export { default } from './Dropdown'
2
- export type { DropdownProps } from './Dropdown'
3
-
4
- export { default as DropdownButton } from './DropdownButton'
5
- export type { DropdownButtonProps } from './DropdownButton'
6
-
7
- export { default as DropdownItem } from './DropdownItem'
8
- export type { DropdownItemProps } from './DropdownItem'
9
-
10
- export { default as DropdownMenu } from './DropdownMenu'
11
- export type { DropdownMenuProps } from './DropdownMenu'