etudes 5.3.1 → 6.1.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 (93) hide show
  1. package/components/Accordion.d.ts +209 -0
  2. package/components/Accordion.js +37 -98
  3. package/components/BurgerButton.d.ts +26 -0
  4. package/components/BurgerButton.js +33 -52
  5. package/components/Button.d.ts +10 -0
  6. package/components/Button.js +15 -0
  7. package/components/Carousel.d.ts +53 -0
  8. package/components/Carousel.js +7 -8
  9. package/components/Collection.d.ts +171 -0
  10. package/components/Collection.js +4 -4
  11. package/components/Counter.d.ts +14 -0
  12. package/components/Counter.js +59 -33
  13. package/components/CoverImage.d.ts +20 -0
  14. package/components/CoverImage.js +21 -22
  15. package/components/CoverVideo.d.ts +20 -0
  16. package/components/CoverVideo.js +20 -21
  17. package/components/Dial.d.ts +79 -0
  18. package/components/Dial.js +10 -19
  19. package/components/Dropdown.d.ts +102 -0
  20. package/components/Dropdown.js +18 -51
  21. package/components/FlatSVG.d.ts +72 -0
  22. package/components/FlatSVG.js +1 -1
  23. package/components/Image.d.ts +144 -0
  24. package/components/Image.js +1 -1
  25. package/components/MasonryGrid.d.ts +28 -0
  26. package/components/MasonryGrid.js +10 -11
  27. package/components/OptionButton.d.ts +19 -0
  28. package/components/OptionButton.js +17 -0
  29. package/components/Panorama.d.ts +77 -0
  30. package/components/Panorama.js +3 -3
  31. package/components/PanoramaSlider.d.ts +63 -0
  32. package/components/PanoramaSlider.js +14 -41
  33. package/components/RangeSlider.d.ts +34 -0
  34. package/components/RangeSlider.js +27 -61
  35. package/components/SelectableButton.d.ts +21 -0
  36. package/components/SelectableButton.js +7 -10
  37. package/components/Slider.d.ts +151 -0
  38. package/components/Slider.js +15 -34
  39. package/components/StepwiseSlider.d.ts +198 -0
  40. package/components/StepwiseSlider.js +13 -33
  41. package/components/SwipeContainer.d.ts +21 -0
  42. package/components/SwipeContainer.js +3 -3
  43. package/components/TextField.d.ts +23 -0
  44. package/components/TextField.js +3 -2
  45. package/components/Video.d.ts +38 -0
  46. package/components/Video.js +1 -1
  47. package/components/WithTooltip.d.ts +36 -0
  48. package/components/WithTooltip.js +144 -167
  49. package/hooks/useClickOutsideEffect.d.ts +2 -0
  50. package/hooks/useDragEffect.d.ts +48 -0
  51. package/hooks/useDragEffect.js +3 -3
  52. package/hooks/useDragValueEffect.d.ts +56 -0
  53. package/hooks/useImageSize.d.ts +21 -0
  54. package/hooks/useImageSize.js +1 -1
  55. package/hooks/useInterval.d.ts +18 -0
  56. package/hooks/useLoadImageEffect.d.ts +43 -0
  57. package/hooks/useLoadVideoMetadataEffect.d.ts +35 -0
  58. package/hooks/useMounted.d.ts +1 -0
  59. package/hooks/usePrevious.d.ts +19 -0
  60. package/hooks/useRect.d.ts +11 -0
  61. package/hooks/useRect.js +1 -1
  62. package/hooks/useResizeEffect.d.ts +17 -0
  63. package/hooks/useScrollPositionEffect.d.ts +13 -0
  64. package/hooks/useScrollPositionEffect.js +4 -4
  65. package/hooks/useSearchParamState.d.ts +34 -0
  66. package/hooks/useSize.d.ts +10 -0
  67. package/hooks/useSize.js +1 -1
  68. package/hooks/useTimeout.d.ts +10 -0
  69. package/hooks/useVideoSize.d.ts +21 -0
  70. package/hooks/useVideoSize.js +1 -1
  71. package/hooks/useViewportSize.d.ts +7 -0
  72. package/hooks/useViewportSize.js +1 -1
  73. package/operators/Conditional.d.ts +5 -0
  74. package/operators/Each.d.ts +7 -0
  75. package/operators/ExtractChild.d.ts +8 -0
  76. package/operators/ExtractChildren.d.ts +6 -0
  77. package/operators/Repeat.d.ts +11 -0
  78. package/package.json +20 -21
  79. package/providers/ScrollPositionProvider.d.ts +15 -0
  80. package/providers/ScrollPositionProvider.js +12 -12
  81. package/utils/asClassNameDict.d.ts +3 -0
  82. package/utils/asComponentDict.d.ts +5 -0
  83. package/utils/asStyleDict.d.ts +4 -0
  84. package/utils/cloneStyledElement.d.ts +17 -0
  85. package/utils/cloneStyledElement.js +2 -3
  86. package/utils/index.d.ts +5 -0
  87. package/utils/styles.d.ts +2 -0
  88. package/components/DebugConsole.js +0 -76
  89. package/components/RotatingGallery.js +0 -58
  90. package/components/index.js +0 -24
  91. package/hooks/index.js +0 -17
  92. package/operators/index.js +0 -5
  93. package/providers/index.js +0 -1
@@ -0,0 +1,209 @@
1
+ import { type ComponentType, type HTMLAttributes, type PropsWithChildren, type ReactElement, type Ref } from 'react';
2
+ import { type CollectionItemProps, type CollectionOrientation, type CollectionProps, type CollectionSelectionMode } from './Collection.js';
3
+ import type { DropdownToggleProps } from './Dropdown.js';
4
+ /**
5
+ * Type describing the current item selection of {@link Accordion}, composed of
6
+ * a dictionary whose key corresponds the section index and value corresponds to
7
+ * an array of selected item indices. If the selection mode of the
8
+ * {@link Accordion} is `single`, only one key will be present and one index in
9
+ * the array value.
10
+ */
11
+ export type AccordionSelection = Record<number, number[]>;
12
+ /**
13
+ * Type describing the data of each section in {@link Accordion}.
14
+ */
15
+ export type AccordionSection<T> = Pick<CollectionProps<T>, 'isSelectionTogglable' | 'itemLength' | 'itemPadding' | 'items' | 'layout' | 'numSegments'> & {
16
+ /**
17
+ * Padding (in pixels) between the sectionheader and the internal collection.
18
+ */
19
+ collectionPadding?: number;
20
+ /**
21
+ * Label for the section header.
22
+ */
23
+ label: string;
24
+ /**
25
+ * Maximum number of visible rows (if section orientation is `vertical`) or
26
+ * columns (if section orientation is `horizontal`). If number of rows exceeds
27
+ * the number of visible, a scrollbar will be put in place.
28
+ */
29
+ maxVisible?: number;
30
+ };
31
+ /**
32
+ * Type describing the props of each `ItemComponent` provided to
33
+ * {@link Accordion}.
34
+ */
35
+ export type AccordionItemProps<T> = CollectionItemProps<T>;
36
+ /**
37
+ * Type describing the props of each `HeaderComponent` provided to
38
+ * {@link Accordion}.
39
+ */
40
+ export type AccordionHeaderProps<I, S extends AccordionSection<I> = AccordionSection<I>> = HTMLAttributes<HTMLElement> & PropsWithChildren<{
41
+ /**
42
+ * The index of the corresponding section.
43
+ */
44
+ index: number;
45
+ /**
46
+ * Indicates whether the corresponding section is collapsed.
47
+ */
48
+ isCollapsed: boolean;
49
+ /**
50
+ * Data provided to the corresponding section.
51
+ */
52
+ section: S;
53
+ /**
54
+ * Handler invoked to dispatch a custom event.
55
+ *
56
+ * @param name User-defined name of the custom event.
57
+ * @param info Optional user-defined info of the custom event.
58
+ */
59
+ onCustomEvent?: (name: string, info?: any) => void;
60
+ }>;
61
+ /**
62
+ * Type describing the props of {@link Accordion}.
63
+ */
64
+ export type AccordionProps<I, S extends AccordionSection<I> = AccordionSection<I>> = HTMLAttributes<HTMLDivElement> & PropsWithChildren<{
65
+ /**
66
+ * Specifies if expanded sections should automatically collapse upon expanding
67
+ * another section.
68
+ */
69
+ autoCollapseSections?: boolean;
70
+ /**
71
+ * Indices of sections that are expanded. If specified, the component will not
72
+ * manage expansion states.
73
+ */
74
+ expandedSectionIndices?: number[];
75
+ /**
76
+ * Orientation of this component.
77
+ *
78
+ * @see {@link CollectionOrientation}
79
+ */
80
+ orientation?: CollectionOrientation;
81
+ /**
82
+ * Padding (in pixels) between each section.
83
+ */
84
+ sectionPadding?: number;
85
+ /**
86
+ * Data provided to each section.
87
+ */
88
+ sections: S[];
89
+ /**
90
+ * Indices of selected items per section.
91
+ *
92
+ * @see {@link AccordionSelection}
93
+ */
94
+ selection?: AccordionSelection;
95
+ /**
96
+ * Selection mode of each section.
97
+ *
98
+ * @see {@link CollectionSelectionMode}
99
+ */
100
+ selectionMode?: CollectionSelectionMode;
101
+ /**
102
+ * Handler invoked when an item is activated in a section. The order of
103
+ * handlers invoked when any selection changes take place is:
104
+ * 1. `onActivateAt`
105
+ * 2. `onDeselectAt`
106
+ * 3. `onSelectAt`
107
+ * 4. `onSelectionChange`
108
+ *
109
+ * @param itemIndex Item index.
110
+ * @param sectionIndex Section index.
111
+ */
112
+ onActivateAt?: (itemIndex: number, sectionIndex: number) => void;
113
+ /**
114
+ * Handler invoked when a section is collapsed. The order of handlers invoked
115
+ * when any section expansion changes take place is:
116
+ * 1. `onCollapseSectionAt`
117
+ * 2. `onExpandSectionAt`
118
+ *
119
+ * @param sectionIndex Section index.
120
+ */
121
+ onCollapseSectionAt?: (sectionIndex: number) => void;
122
+ /**
123
+ * Handler invoked when an item is deselected in a section. The order of
124
+ * handlers invoked when any selection changes take place is:
125
+ * 1. `onActivateAt`
126
+ * 2. `onDeselectAt`
127
+ * 3. `onSelectAt`
128
+ * 4. `onSelectionChange`
129
+ *
130
+ * @param itemIndex Item index.
131
+ * @param sectionIndex Section index.
132
+ */
133
+ onDeselectAt?: (itemIndex: number, sectionIndex: number) => void;
134
+ /**
135
+ * Handler invoked when the expansion state of any section changes.
136
+ *
137
+ * @param expandedSectionIndices Indices of sections that are expanded.
138
+ */
139
+ onExpandedSectionsChange?: (expandedSectionIndices: number[]) => void;
140
+ /**
141
+ * Handler invoked when a section is expanded. The order of handlers invoked
142
+ * when any section expansion changes take place is:
143
+ * 1. `onCollapseSectionAt`
144
+ * 2. `onExpandSectionAt`
145
+ *
146
+ * @param sectionIndex Section index.
147
+ */
148
+ onExpandSectionAt?: (sectionIndex: number) => void;
149
+ /**
150
+ * Handler invoked when a custom event is dispatched from a section header.
151
+ *
152
+ * @param sectionIndex Index of the section which the header belongs.
153
+ * @param eventName User-defined name of the dispatched event.
154
+ * @param eventInfo Optional user-defined info of the dispatched event.
155
+ */
156
+ onHeaderCustomEvent?: (sectionIndex: number, eventName: string, eventInfo?: any) => void;
157
+ /**
158
+ * Handler invoked when a custom event is dispatched from an item.
159
+ *
160
+ * @param itemIndex Item index.
161
+ * @param sectionIndex Section index.
162
+ * @param eventName User-defined name of the dispatched event.
163
+ * @param eventInfo Optional user-defined info of the dispatched event.
164
+ */
165
+ onItemCustomEvent?: (itemIndex: number, sectionIndex: number, eventName: string, eventInfo?: any) => void;
166
+ /**
167
+ * Handler invoked when an item is selected in a section. The order of
168
+ * handlers invoked when any selection changes take place is:
169
+ * 1. `onActivateAt`
170
+ * 2. `onDeselectAt`
171
+ * 3. `onSelectAt`
172
+ * 4. `onSelectionChange`
173
+ *
174
+ * @param itemIndex Item index.
175
+ * @param sectionIndex Section index.
176
+ */
177
+ onSelectAt?: (itemIndex: number, sectionIndex: number) => void;
178
+ /**
179
+ * Handler invoked when selected items have changed. The order of handlers
180
+ * invoked when any selection changes take place is:
181
+ * 1. `onActivateAt`
182
+ * 2. `onDeselectAt`
183
+ * 3. `onSelectAt`
184
+ * 4. `onSelectionChange`
185
+ *
186
+ * @param selectedIndices Dictionary of indices of selected items per section.
187
+ */
188
+ onSelectionChange?: (selection: AccordionSelection) => void;
189
+ /**
190
+ * Component type for generating section headers inside the component. When
191
+ * absent, one will be generated automatically.
192
+ */
193
+ HeaderComponent?: ComponentType<AccordionHeaderProps<I, S>>;
194
+ /**
195
+ * Component type for generating items for each section.
196
+ */
197
+ ItemComponent?: ComponentType<AccordionItemProps<I>>;
198
+ }>;
199
+ /**
200
+ * A collection of selectable items laid out in sections in an accordion. Items
201
+ * are generated based on the provided `ItemComponent` while each section header
202
+ * is optionally provided by `HeaderComponent` or generated automatically.
203
+ */
204
+ export declare const Accordion: <I, S extends AccordionSection<I> = AccordionSection<I>>(props: AccordionProps<I, S> & {
205
+ ref?: Ref<HTMLDivElement>;
206
+ }) => ReactElement;
207
+ export declare const AccordionHeader: ({ children, ...props }: HTMLAttributes<HTMLButtonElement> & PropsWithChildren<DropdownToggleProps>) => import("react/jsx-runtime").JSX.Element;
208
+ export declare const AccordionExpandIcon: ({ children, ...props }: HTMLAttributes<HTMLDivElement> & PropsWithChildren) => import("react/jsx-runtime").JSX.Element;
209
+ export declare const AccordionCollapseIcon: ({ children, ...props }: HTMLAttributes<HTMLDivElement> & PropsWithChildren) => import("react/jsx-runtime").JSX.Element;
@@ -1,17 +1,16 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import clsx from 'clsx';
3
3
  import isDeepEqual from 'fast-deep-equal/react';
4
4
  import { forwardRef, useEffect, useRef } from 'react';
5
5
  import { Each } from '../operators/Each.js';
6
- import { asStyleDict, cloneStyledElement, styles } from '../utils/index.js';
6
+ import { asComponentDict, asStyleDict, cloneStyledElement, styles } from '../utils/index.js';
7
7
  import { Collection } from './Collection.js';
8
- import { FlatSVG } from './FlatSVG.js';
9
8
  /**
10
9
  * A collection of selectable items laid out in sections in an accordion. Items
11
10
  * are generated based on the provided `ItemComponent` while each section header
12
11
  * is optionally provided by `HeaderComponent` or generated automatically.
13
12
  */
14
- export const Accordion = forwardRef(({ children, style, autoCollapseSections = false, collapseIconSvg, expandedSectionIndices: externalExpandedSectionIndices, expandIconSvg, orientation = 'vertical', sectionPadding = 0, sections, selection: externalSelection, selectionMode = 'single', usesDefaultStyles = false, onActivateAt, onCollapseSectionAt, onDeselectAt, onExpandedSectionsChange, onExpandSectionAt, onHeaderCustomEvent, onItemCustomEvent, onSelectAt, onSelectionChange, HeaderComponent, ItemComponent, ...props }, ref) => {
13
+ export const Accordion = forwardRef(({ children, style, autoCollapseSections = false, expandedSectionIndices: externalExpandedSectionIndices, orientation = 'vertical', sectionPadding = 0, sections, selection: externalSelection, selectionMode = 'single', onActivateAt, onCollapseSectionAt, onDeselectAt, onExpandedSectionsChange, onExpandSectionAt, onHeaderCustomEvent, onItemCustomEvent, onSelectAt, onSelectionChange, HeaderComponent, ItemComponent, ...props }, ref) => {
15
14
  const isSectionIndexOutOfRange = (sectionIndex) => {
16
15
  if (sectionIndex >= sections.length)
17
16
  return true;
@@ -119,51 +118,63 @@ export const Accordion = forwardRef(({ children, style, autoCollapseSections = f
119
118
  const selection = sanitizeSelection(externalSelection ?? {});
120
119
  const expandedSectionIndices = sanitizeExpandedSectionIndices(externalExpandedSectionIndices ?? []);
121
120
  const fixedStyles = getFixedStyles({ orientation });
122
- const defaultStyles = usesDefaultStyles ? getDefaultStyles({ orientation }) : undefined;
123
121
  const prevSelectionRef = useRef();
124
122
  const prevSelection = prevSelectionRef.current;
123
+ const components = asComponentDict(children, {
124
+ collapseIcon: AccordionCollapseIcon,
125
+ expandIcon: AccordionExpandIcon,
126
+ header: AccordionHeader,
127
+ });
125
128
  useEffect(() => {
126
129
  prevSelectionRef.current = selection;
127
130
  if (prevSelection === undefined)
128
131
  return;
129
132
  handleSelectionChange(prevSelection, selection);
130
133
  }, [JSON.stringify(selection)]);
131
- return (_jsx("div", { ...props, ref: ref, "data-component": 'accordion', style: styles(style, fixedStyles.root), children: _jsx(Each, { in: sections, children: (section, sectionIndex) => {
134
+ return (_jsx("div", { ...props, ref: ref, style: styles(style, fixedStyles.root), children: _jsx(Each, { in: sections, children: (section, sectionIndex) => {
132
135
  const { collectionPadding = 0, items, itemLength = 50, itemPadding = 0, isSelectionTogglable, layout = 'list', maxVisible = -1, numSegments = 1 } = section;
133
136
  const allVisible = layout === 'list' ? items.length : Math.ceil(items.length / numSegments);
134
137
  const numVisible = maxVisible < 0 ? allVisible : Math.min(allVisible, maxVisible);
135
138
  const maxLength = itemLength * numVisible + itemPadding * (numVisible - 1);
136
139
  const isCollapsed = !isSectionExpandedAt(sectionIndex);
137
- const expandIconComponent = expandIconSvg ? _jsx(FlatSVG, { style: defaultStyles?.expandIcon, svg: expandIconSvg }) : _jsx(_Fragment, {});
138
- const collapseIconComponent = collapseIconSvg ? _jsx(FlatSVG, { style: defaultStyles?.collapseIcon, svg: collapseIconSvg }) : expandIconComponent;
139
140
  return (_jsxs("div", { style: styles(fixedStyles.section, orientation === 'vertical' ? {
140
141
  marginTop: sectionIndex === 0 ? '0px' : `${sectionPadding}px`,
141
142
  } : {
142
143
  marginLeft: sectionIndex === 0 ? '0px' : `${sectionPadding}px`,
143
- }), children: [HeaderComponent ? (_jsx(HeaderComponent, { className: clsx({ collapsed: isCollapsed, expanded: !isCollapsed }), "data-child": 'header', index: sectionIndex, isCollapsed: isCollapsed, section: section, style: styles(fixedStyles.header), onClick: () => toggleSectionAt(sectionIndex), onCustomEvent: (name, info) => onHeaderCustomEvent?.(sectionIndex, name, info) })) : (_jsxs("button", { className: clsx({ collapsed: isCollapsed, expanded: !isCollapsed }), "data-child": 'header', style: styles(fixedStyles.header, defaultStyles?.header), onClick: () => toggleSectionAt(sectionIndex), children: [_jsx("span", { dangerouslySetInnerHTML: { __html: section.label }, style: styles(defaultStyles?.headerLabel) }), cloneStyledElement(isCollapsed ? expandIconComponent : collapseIconComponent, {
144
- style: styles(isCollapsed ? fixedStyles.expandIcon : fixedStyles.collapseIcon),
145
- })] })), _jsx(Collection, { className: clsx({ collapsed: isCollapsed, expanded: !isCollapsed }), "data-child": 'collection', isSelectionTogglable: isSelectionTogglable, ItemComponent: ItemComponent, itemLength: itemLength, itemPadding: itemPadding, items: items, layout: layout, numSegments: numSegments, orientation: orientation, selection: selection[sectionIndex] ?? [], selectionMode: selectionMode, style: styles(fixedStyles.list, defaultStyles?.collection, orientation === 'vertical' ? {
144
+ }), children: [HeaderComponent ? (_jsx(HeaderComponent, { "aria-expanded": !isCollapsed, className: clsx({ collapsed: isCollapsed, expanded: !isCollapsed }), index: sectionIndex, isCollapsed: isCollapsed, role: 'button', section: section, style: styles(fixedStyles.header), onClick: () => toggleSectionAt(sectionIndex), onCustomEvent: (name, info) => onHeaderCustomEvent?.(sectionIndex, name, info) })) : (cloneStyledElement(components.header ?? _jsx(AccordionHeader, {}), {
145
+ 'aria-expanded': !isCollapsed,
146
+ 'className': clsx({ collapsed: isCollapsed, expanded: !isCollapsed }),
147
+ 'style': styles(fixedStyles.header),
148
+ 'role': 'button',
149
+ 'onClick': () => toggleSectionAt(sectionIndex),
150
+ }, _jsx("span", { dangerouslySetInnerHTML: { __html: section.label } }), isCollapsed ? components.collapseIcon ?? components.expandIcon : components.expandIcon)), _jsx("div", { hidden: isCollapsed, role: 'region', style: styles(orientation === 'vertical' ? {
146
151
  width: '100%',
147
- height: isCollapsed ? '0px' : `${maxLength}px`,
148
- marginTop: isCollapsed ? '0px' : `${collectionPadding}px`,
152
+ height: isCollapsed ? '0' : `${maxLength}px`,
153
+ marginTop: isCollapsed ? '0' : `${collectionPadding}px`,
149
154
  overflowY: maxVisible < 0 || maxVisible >= allVisible ? 'hidden' : 'scroll',
150
155
  } : {
151
- marginLeft: isCollapsed ? '0px' : `${collectionPadding}px`,
156
+ marginLeft: isCollapsed ? '0' : `${collectionPadding}px`,
152
157
  overflowX: maxVisible < 0 || maxVisible >= allVisible ? 'hidden' : 'scroll',
153
- width: isCollapsed ? '0px' : `${maxLength}px`,
158
+ width: isCollapsed ? '0' : `${maxLength}px`,
154
159
  height: '100%',
155
- }), onActivateAt: itemIndex => {
156
- onActivateAt?.(itemIndex, sectionIndex);
157
- }, onDeselectAt: itemIndex => {
158
- handleDeselectAt?.(itemIndex, sectionIndex);
159
- }, onItemCustomEvent: (itemIndex, name, info) => {
160
- onItemCustomEvent?.(itemIndex, sectionIndex, name, info);
161
- }, onSelectAt: itemIndex => {
162
- handleSelectAt?.(itemIndex, sectionIndex);
163
- } })] }));
160
+ }), children: _jsx(Collection, { className: clsx({ collapsed: isCollapsed, expanded: !isCollapsed }), isSelectionTogglable: isSelectionTogglable, ItemComponent: ItemComponent, itemLength: itemLength, itemPadding: itemPadding, items: items, layout: layout, numSegments: numSegments, orientation: orientation, selection: selection[sectionIndex] ?? [], selectionMode: selectionMode, style: styles(orientation === 'vertical' ? {
161
+ width: '100%',
162
+ } : {
163
+ height: '100%',
164
+ }), onActivateAt: itemIndex => {
165
+ onActivateAt?.(itemIndex, sectionIndex);
166
+ }, onCustomEvent: (itemIndex, name, info) => {
167
+ onItemCustomEvent?.(itemIndex, sectionIndex, name, info);
168
+ }, onDeselectAt: itemIndex => {
169
+ handleDeselectAt?.(itemIndex, sectionIndex);
170
+ }, onSelectAt: itemIndex => {
171
+ handleSelectAt?.(itemIndex, sectionIndex);
172
+ } }) })] }));
164
173
  } }) }));
165
174
  });
166
- Object.defineProperty(Accordion, 'displayName', { value: 'Accordion', writable: false });
175
+ export const AccordionHeader = ({ children, ...props }) => (_jsx("button", { ...props, children: children }));
176
+ export const AccordionExpandIcon = ({ children, ...props }) => (_jsx("figure", { ...props, children: children }));
177
+ export const AccordionCollapseIcon = ({ children, ...props }) => (_jsx("figure", { ...props, children: children }));
167
178
  function sortIndices(indices) {
168
179
  return indices.sort((a, b) => a - b);
169
180
  }
@@ -199,7 +210,6 @@ function getFixedStyles({ orientation = 'vertical' }) {
199
210
  height: '100%',
200
211
  },
201
212
  },
202
- list: {},
203
213
  header: {
204
214
  cursor: 'pointer',
205
215
  margin: '0',
@@ -209,77 +219,6 @@ function getFixedStyles({ orientation = 'vertical' }) {
209
219
  height: '100%',
210
220
  },
211
221
  },
212
- expandIcon: {
213
- margin: '0',
214
- padding: '0',
215
- },
216
- collapseIcon: {
217
- margin: '0',
218
- padding: '0',
219
- },
220
- });
221
- }
222
- function getDefaultStyles({ orientation = 'vertical' }) {
223
- return asStyleDict({
224
- collection: {
225
- transitionDuration: '100ms',
226
- transitionTimingFunction: 'ease-out',
227
- ...orientation === 'vertical' ? {
228
- transitionProperty: 'height, margin',
229
- } : {
230
- transitionProperty: 'width, margin',
231
- },
232
- },
233
- header: {
234
- border: 'none',
235
- outline: 'none',
236
- alignItems: 'center',
237
- background: '#fff',
238
- boxSizing: 'border-box',
239
- display: 'flex',
240
- flexDirection: 'row',
241
- justifyContent: 'space-between',
242
- padding: '0 10px',
243
- transitionDuration: '100ms',
244
- transitionProperty: 'transform, opacity, background, color',
245
- transitionTimingFunction: 'ease-out',
246
- ...orientation === 'vertical' ? {
247
- height: '50px',
248
- } : {
249
- width: '50px',
250
- },
251
- },
252
- headerLabel: {
253
- color: 'inherit',
254
- fontFamily: 'inherit',
255
- fontSize: 'inherit',
256
- fontWeight: 'inherit',
257
- letterSpacing: 'inherit',
258
- lineHeight: 'inherit',
259
- pointerEvents: 'none',
260
- transition: 'inherit',
261
- },
262
- expandIcon: {
263
- boxSizing: 'border-box',
264
- display: 'block',
265
- fill: '#000',
266
- height: '15px',
267
- transformOrigin: 'center',
268
- transitionDuration: '100ms',
269
- transitionProperty: 'transform',
270
- transitionTimingFunction: 'ease-out',
271
- width: '15px',
272
- },
273
- collapseIcon: {
274
- boxSizing: 'border-box',
275
- display: 'block',
276
- fill: '#000',
277
- height: '15px',
278
- transformOrigin: 'center',
279
- transitionDuration: '100ms',
280
- transitionProperty: 'transform',
281
- transitionTimingFunction: 'ease-out',
282
- width: '15px',
283
- },
284
222
  });
285
223
  }
224
+ Object.defineProperty(Accordion, 'displayName', { value: 'Accordion', writable: false });
@@ -0,0 +1,26 @@
1
+ import { type HTMLAttributes, type PropsWithChildren } from 'react';
2
+ export type BurgerButtonProps = HTMLAttributes<HTMLButtonElement> & PropsWithChildren<{
3
+ isActive?: boolean;
4
+ isSplit?: boolean;
5
+ isTailHidden?: boolean;
6
+ onActivate?: () => void;
7
+ onDeactivate?: () => void;
8
+ onToggle?: (isActive: boolean) => void;
9
+ }>;
10
+ /**
11
+ * Three-striped burger button component that transforms into an "X" when
12
+ * selected.
13
+ *
14
+ * @exports BurgerButtonBar Component for each bar in the burger button.
15
+ */
16
+ export declare const BurgerButton: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLButtonElement> & {
17
+ isActive?: boolean;
18
+ isSplit?: boolean;
19
+ isTailHidden?: boolean;
20
+ onActivate?: () => void;
21
+ onDeactivate?: () => void;
22
+ onToggle?: (isActive: boolean) => void;
23
+ } & {
24
+ children?: import("react").ReactNode | undefined;
25
+ } & import("react").RefAttributes<HTMLButtonElement>>;
26
+ export declare const BurgerButtonBar: ({ ...props }: HTMLAttributes<HTMLSpanElement>) => import("react/jsx-runtime").JSX.Element;
@@ -1,29 +1,24 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import clsx from 'clsx';
3
- import { forwardRef, useEffect, useState } from 'react';
3
+ import { forwardRef } from 'react';
4
4
  import { Repeat } from '../operators/Repeat.js';
5
5
  import { asClassNameDict, asComponentDict, asStyleDict, cloneStyledElement, styles } from '../utils/index.js';
6
6
  /**
7
7
  * Three-striped burger button component that transforms into an "X" when
8
8
  * selected.
9
9
  *
10
- * @exports BurgerButtonBar Component for each line on the burger button.
10
+ * @exports BurgerButtonBar Component for each bar in the burger button.
11
11
  */
12
- export const BurgerButton = forwardRef(({ children, className, style, height = 20, isActive: externalIsActive = false, isDoubleJointed = false, isLastBarHalfWidth = false, thickness = 2, transitionDuration = 200, usesDefaultStyles = false, width = 20, onActivate, onDeactivate, ...props }, ref) => {
13
- const [isActive, setIsActive] = useState(externalIsActive);
14
- useEffect(() => {
15
- if (isActive === externalIsActive)
16
- return;
17
- setIsActive(externalIsActive);
18
- }, [externalIsActive]);
19
- useEffect(() => {
12
+ export const BurgerButton = forwardRef(({ children, className, style, isActive = false, isTailHidden = false, isSplit = false, onActivate, onDeactivate, onToggle, ...props }, ref) => {
13
+ const onClick = () => {
14
+ onToggle?.(isActive);
20
15
  if (isActive) {
21
- onActivate?.();
16
+ onDeactivate?.();
22
17
  }
23
18
  else {
24
- onDeactivate?.();
19
+ onActivate?.();
25
20
  }
26
- }, [isActive]);
21
+ };
27
22
  const components = asComponentDict(children, {
28
23
  bar: BurgerButtonBar,
29
24
  });
@@ -35,30 +30,26 @@ export const BurgerButton = forwardRef(({ children, className, style, height = 2
35
30
  active: isActive,
36
31
  }),
37
32
  });
38
- const fixedStyles = getFixedStyles({ height, width, isDoubleJointed, thickness, isActive, isLastBarHalfWidth });
39
- const defaultStyles = usesDefaultStyles ? getDefaultStyles() : undefined;
40
- return (_jsx("button", { ...props, ref: ref, className: clsx(className, fixedClassNames.root), "data-component": 'burger-button', style: styles(style, fixedStyles.root), onClick: () => setIsActive(!isActive), children: _jsx(Repeat, { count: isDoubleJointed ? 2 : 1, children: j => (_jsx("div", { "data-child": 'joint', style: styles(fixedStyles.joint, fixedStyles[`joint${j}`]), children: _jsx(Repeat, { count: 3, children: i => cloneStyledElement(components.bar ?? _jsx(BurgerButtonBar, { style: defaultStyles?.bar }), {
33
+ const fixedStyles = getFixedStyles({ isSplit, isActive, isTailHidden });
34
+ return (_jsx("button", { ...props, ref: ref, "aria-expanded": isActive, className: clsx(className, fixedClassNames.root), style: styles(style, fixedStyles.root), onClick: onClick, children: _jsx(Repeat, { count: isSplit ? 2 : 1, children: j => (_jsx("div", { "aria-hidden": true, style: styles(fixedStyles.section, fixedStyles[`section${j}`]), children: _jsx(Repeat, { count: 3, children: i => cloneStyledElement(components.bar ?? _jsx(BurgerButtonBar, {}), {
35
+ 'aria-hidden': true,
41
36
  'className': clsx(fixedClassNames.bar),
42
37
  'style': styles(fixedStyles.bar, fixedStyles[`bar${j}${i}`]),
43
- 'data-index': i,
44
38
  }) }) })) }) }));
45
39
  });
46
- Object.defineProperty(BurgerButton, 'displayName', { value: 'BurgerButton', writable: false });
47
- export const BurgerButtonBar = ({ ...props }) => _jsx("span", { ...props, "data-child": 'bar' });
48
- function getFixedStyles({ height = 0, width = 0, isDoubleJointed = false, thickness = 0, isActive = false, isLastBarHalfWidth = false }) {
40
+ export const BurgerButtonBar = ({ ...props }) => (_jsx("span", { ...props }));
41
+ function getFixedStyles({ isActive = false, isSplit = false, isTailHidden = false }) {
49
42
  return asStyleDict({
50
43
  root: {
51
44
  background: 'transparent',
52
45
  border: 'none',
53
46
  display: 'block',
54
- height: `${height}px`,
55
47
  outline: 'none',
56
- width: `${width}px`,
57
48
  },
58
- joint: {
49
+ section: {
59
50
  height: '100%',
60
51
  position: 'absolute',
61
- width: isDoubleJointed ? '50%' : '100%',
52
+ width: isSplit ? '50%' : '100%',
62
53
  },
63
54
  joint0: {
64
55
  left: '0',
@@ -69,7 +60,6 @@ function getFixedStyles({ height = 0, width = 0, isDoubleJointed = false, thickn
69
60
  top: '0',
70
61
  },
71
62
  bar: {
72
- height: `${thickness}px`,
73
63
  margin: '0',
74
64
  padding: '0',
75
65
  position: 'absolute',
@@ -77,51 +67,42 @@ function getFixedStyles({ height = 0, width = 0, isDoubleJointed = false, thickn
77
67
  },
78
68
  bar00: {
79
69
  left: '0',
80
- top: '0',
81
- transform: isActive ? `translate3d(0, ${height * 0.5 - thickness * 0.5}px, 0) rotate(45deg)` : 'translate3d(0, 0, 0) rotate(0deg)',
82
- transformOrigin: isDoubleJointed ? 'right center' : 'center',
70
+ top: isActive ? '50%' : '0',
71
+ transform: isActive ? 'translate(0, -50%) rotate(45deg)' : 'translate(0, 0) rotate(0deg)',
72
+ transformOrigin: isSplit ? 'right center' : 'center',
83
73
  },
84
74
  bar01: {
85
75
  left: '0',
86
- top: `${height * 0.5 - thickness * 0.5}px`,
87
- transform: isActive ? 'translate3d(0, 0, 0) scale(0)' : 'translate3d(0, 0, 0) scale(1)',
88
- transformOrigin: isDoubleJointed ? 'right center' : 'center',
76
+ top: '50%',
77
+ transform: isActive ? 'translate(0, -50%) scale(0)' : 'translate(0, -50%) scale(1)',
78
+ transformOrigin: isSplit ? 'right center' : 'center',
89
79
  },
90
80
  bar02: {
91
81
  left: '0',
92
- top: `${height - thickness}px`,
93
- transform: isActive ? `translate3d(0, ${thickness * 0.5 - height * 0.5}px, 0) rotate(-45deg)` : 'translate3d(0, 0, 0) rotate(0deg)',
94
- transformOrigin: isDoubleJointed ? 'right center' : 'center',
95
- width: isActive || isDoubleJointed ? '100%' : `${isLastBarHalfWidth ? '50%' : '100%'}`,
82
+ top: isActive ? '50%' : '100%',
83
+ transform: isActive ? 'translate(0, -50%) rotate(-45deg)' : 'translate(0, -100%) rotate(0deg)',
84
+ transformOrigin: isSplit ? 'right center' : 'center',
85
+ width: isActive || isSplit ? '100%' : `${isTailHidden ? '50%' : '100%'}`,
96
86
  },
97
87
  bar10: {
98
88
  left: '0',
99
- top: '0',
100
- transform: isActive ? `translate3d(0, ${height * 0.5 - thickness * 0.5}px, 0) rotate(-45deg)` : 'translate3d(0, 0, 0) rotate(0deg)',
89
+ top: isActive ? '50%' : '0',
90
+ transform: isActive ? 'translate(0, -50%) rotate(-45deg)' : 'translate(0, 0) rotate(0deg)',
101
91
  transformOrigin: 'left center',
102
92
  },
103
93
  bar11: {
104
94
  left: '0',
105
- top: `${height * 0.5 - thickness * 0.5}px`,
106
- transform: isActive ? 'translate3d(0, 0, 0) scale(0)' : 'translate3d(0, 0, 0) scale(1)',
95
+ top: '50%',
96
+ transform: isActive ? 'translate(0, -50%) scale(0)' : 'translate(0, -50%) scale(1)',
107
97
  transformOrigin: 'left center',
108
98
  },
109
99
  bar12: {
110
100
  left: '0',
111
- top: `${height - thickness}px`,
112
- transform: isActive ? `translate3d(0, ${thickness * 0.5 - height * 0.5}px, 0) rotate(45deg)` : 'translate3d(0, 0, 0) rotate(0deg)',
101
+ top: isActive ? '50%' : '100%',
102
+ transform: isActive ? 'translate(0, -50%) rotate(45deg)' : 'translate(0, -100%) rotate(0deg)',
113
103
  transformOrigin: 'left center',
114
- width: isLastBarHalfWidth && !isActive ? '0' : '100%',
115
- },
116
- });
117
- }
118
- function getDefaultStyles() {
119
- return asStyleDict({
120
- bar: {
121
- background: '#fff',
122
- transitionDuration: '100ms',
123
- transitionProperty: 'width, height, transform, opacity, background',
124
- transitionTimingFunction: 'ease-out',
104
+ width: isTailHidden && !isActive ? '0' : '100%',
125
105
  },
126
106
  });
127
107
  }
108
+ Object.defineProperty(BurgerButton, 'displayName', { value: 'BurgerButton', writable: false });
@@ -0,0 +1,10 @@
1
+ import type { HTMLAttributes, PropsWithChildren } from 'react';
2
+ export type ButtonProps = HTMLAttributes<HTMLElement> & PropsWithChildren<{
3
+ href?: string;
4
+ isDisabled?: boolean;
5
+ label?: string;
6
+ opensInNewTab?: boolean;
7
+ to?: string;
8
+ type?: HTMLButtonElement['type'];
9
+ }>;
10
+ export declare function Button({ children, className, href, isDisabled, label, opensInNewTab, to, type, ...props }: ButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import clsx from 'clsx';
3
+ import { Link } from 'react-router-dom';
4
+ export function Button({ children, className, href, isDisabled = false, label, opensInNewTab, to, type, ...props }) {
5
+ if (href) {
6
+ return (_jsx("a", { ...props, "aria-disabled": isDisabled, "aria-label": label, className: clsx(className, { disabled: isDisabled }), href: href, rel: opensInNewTab ? 'noopener,noreferrer' : undefined, target: opensInNewTab ? '_blank' : undefined, children: children ?? label }));
7
+ }
8
+ else if (to) {
9
+ return (_jsx(Link, { ...props, "aria-disabled": isDisabled, "aria-label": label, className: clsx(className, { disabled: isDisabled }), to: to, children: children ?? label }));
10
+ }
11
+ else {
12
+ return (_jsx("button", { ...props, "aria-disabled": isDisabled, "aria-label": label, className: className, disabled: isDisabled, type: type, children: children ?? label }));
13
+ }
14
+ }
15
+ Object.defineProperty(Button, 'displayName', { value: 'Button', writable: false });