@react-spectrum/card 3.0.0-alpha.33 → 3.0.0-alpha.35
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.
- package/dist/BaseLayout.main.js +11 -16
- package/dist/BaseLayout.main.js.map +1 -1
- package/dist/BaseLayout.mjs +11 -16
- package/dist/BaseLayout.module.js +11 -16
- package/dist/BaseLayout.module.js.map +1 -1
- package/dist/CardBase.main.js +1 -1
- package/dist/CardBase.main.js.map +1 -1
- package/dist/CardBase.mjs +1 -1
- package/dist/CardBase.module.js +1 -1
- package/dist/CardBase.module.js.map +1 -1
- package/dist/CardView.main.js +39 -31
- package/dist/CardView.main.js.map +1 -1
- package/dist/CardView.mjs +40 -32
- package/dist/CardView.module.js +40 -32
- package/dist/CardView.module.js.map +1 -1
- package/dist/GridLayout.main.js +0 -24
- package/dist/GridLayout.main.js.map +1 -1
- package/dist/GridLayout.mjs +0 -24
- package/dist/GridLayout.module.js +0 -24
- package/dist/GridLayout.module.js.map +1 -1
- package/dist/WaterfallLayout.main.js.map +1 -1
- package/dist/WaterfallLayout.module.js.map +1 -1
- package/dist/types.d.ts +12 -11
- package/dist/types.d.ts.map +1 -1
- package/dist/zh-TW.main.js +1 -1
- package/dist/zh-TW.main.js.map +1 -1
- package/dist/zh-TW.mjs +1 -1
- package/dist/zh-TW.module.js +1 -1
- package/dist/zh-TW.module.js.map +1 -1
- package/package.json +20 -20
- package/src/BaseLayout.tsx +22 -19
- package/src/CardBase.tsx +1 -1
- package/src/CardView.tsx +42 -38
- package/src/GridLayout.tsx +0 -35
- package/src/WaterfallLayout.tsx +2 -2
package/src/CardView.tsx
CHANGED
|
@@ -47,7 +47,6 @@ function CardView<T extends object>(props: SpectrumCardViewProps<T>, ref: DOMRef
|
|
|
47
47
|
let cardViewLayout = useMemo(() => typeof layout === 'function' ? new layout({collator, cardOrientation, scale}) : layout, [layout, collator, cardOrientation, scale]);
|
|
48
48
|
let layoutType = cardViewLayout.layoutType;
|
|
49
49
|
|
|
50
|
-
let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/card');
|
|
51
50
|
let {direction} = useLocale();
|
|
52
51
|
let {collection} = useListState(props);
|
|
53
52
|
|
|
@@ -79,8 +78,6 @@ function CardView<T extends object>(props: SpectrumCardViewProps<T>, ref: DOMRef
|
|
|
79
78
|
|
|
80
79
|
cardViewLayout.collection = gridCollection;
|
|
81
80
|
cardViewLayout.disabledKeys = state.disabledKeys;
|
|
82
|
-
cardViewLayout.isLoading = isLoading;
|
|
83
|
-
cardViewLayout.direction = direction;
|
|
84
81
|
|
|
85
82
|
let {gridProps} = useGrid({
|
|
86
83
|
...props,
|
|
@@ -89,7 +86,7 @@ function CardView<T extends object>(props: SpectrumCardViewProps<T>, ref: DOMRef
|
|
|
89
86
|
}, state, domRef);
|
|
90
87
|
|
|
91
88
|
type View = ReusableView<Node<T>, ReactNode>;
|
|
92
|
-
let renderWrapper = (parent: View, reusableView: View) => (
|
|
89
|
+
let renderWrapper = useCallback((parent: View, reusableView: View) => (
|
|
93
90
|
<VirtualizerItem
|
|
94
91
|
key={reusableView.key}
|
|
95
92
|
layoutInfo={reusableView.layoutInfo}
|
|
@@ -97,7 +94,7 @@ function CardView<T extends object>(props: SpectrumCardViewProps<T>, ref: DOMRef
|
|
|
97
94
|
parent={parent?.layoutInfo}>
|
|
98
95
|
{reusableView.rendered}
|
|
99
96
|
</VirtualizerItem>
|
|
100
|
-
);
|
|
97
|
+
), []);
|
|
101
98
|
|
|
102
99
|
let focusedKey = state.selectionManager.focusedKey;
|
|
103
100
|
let focusedItem = gridCollection.getItem(state.selectionManager.focusedKey);
|
|
@@ -105,64 +102,71 @@ function CardView<T extends object>(props: SpectrumCardViewProps<T>, ref: DOMRef
|
|
|
105
102
|
focusedKey = focusedItem.parentKey;
|
|
106
103
|
}
|
|
107
104
|
|
|
108
|
-
let
|
|
109
|
-
let virtualizer = cardViewLayout.virtualizer;
|
|
110
|
-
let scrollToItem = useCallback((key) => {
|
|
111
|
-
virtualizer && virtualizer.scrollToItem(key, {
|
|
112
|
-
duration: 0,
|
|
113
|
-
offsetY: margin
|
|
114
|
-
});
|
|
115
|
-
}, [margin, virtualizer]);
|
|
105
|
+
let persistedKeys = useMemo(() => focusedKey != null ? new Set([focusedKey]) : null, [focusedKey]);
|
|
116
106
|
|
|
117
107
|
// TODO: does aria-row count and aria-col count need to be modified? Perhaps aria-col count needs to be omitted
|
|
118
108
|
return (
|
|
119
|
-
<CardViewContext.Provider value={{state, isQuiet, layout: cardViewLayout, cardOrientation}}>
|
|
109
|
+
<CardViewContext.Provider value={{state, isQuiet, layout: cardViewLayout, cardOrientation, renderEmptyState}}>
|
|
120
110
|
<Virtualizer
|
|
121
111
|
{...gridProps}
|
|
122
112
|
{...styleProps}
|
|
123
113
|
className={classNames(styles, 'spectrum-CardView')}
|
|
124
114
|
ref={domRef}
|
|
125
|
-
|
|
115
|
+
persistedKeys={persistedKeys}
|
|
126
116
|
scrollDirection="vertical"
|
|
127
117
|
layout={cardViewLayout}
|
|
128
118
|
collection={gridCollection}
|
|
129
119
|
isLoading={isLoading}
|
|
130
120
|
onLoadMore={onLoadMore}
|
|
121
|
+
layoutOptions={useMemo(() => ({isLoading, direction}), [isLoading, direction])}
|
|
131
122
|
renderWrapper={renderWrapper}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
123
|
+
style={{
|
|
124
|
+
...styleProps.style,
|
|
125
|
+
scrollPaddingTop: cardViewLayout.margin || 0
|
|
126
|
+
}}>
|
|
127
|
+
{useCallback((type, item) => {
|
|
135
128
|
if (type === 'item') {
|
|
136
129
|
return (
|
|
137
130
|
<InternalCard item={item} />
|
|
138
131
|
);
|
|
139
132
|
} else if (type === 'loader') {
|
|
140
|
-
return
|
|
141
|
-
<CenteredWrapper>
|
|
142
|
-
<ProgressCircle
|
|
143
|
-
isIndeterminate
|
|
144
|
-
aria-label={state.collection.size > 0 ? stringFormatter.format('loadingMore') : stringFormatter.format('loading')} />
|
|
145
|
-
</CenteredWrapper>
|
|
146
|
-
);
|
|
133
|
+
return <LoadingState />;
|
|
147
134
|
} else if (type === 'placeholder') {
|
|
148
|
-
|
|
149
|
-
if (emptyState == null) {
|
|
150
|
-
return null;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return (
|
|
154
|
-
<CenteredWrapper>
|
|
155
|
-
{emptyState}
|
|
156
|
-
</CenteredWrapper>
|
|
157
|
-
);
|
|
135
|
+
return <EmptyState />;
|
|
158
136
|
}
|
|
159
|
-
}}
|
|
137
|
+
}, [])}
|
|
160
138
|
</Virtualizer>
|
|
161
139
|
</CardViewContext.Provider>
|
|
162
140
|
|
|
163
141
|
);
|
|
164
142
|
}
|
|
165
143
|
|
|
144
|
+
function LoadingState() {
|
|
145
|
+
let {state} = useCardViewContext();
|
|
146
|
+
let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/card');
|
|
147
|
+
return (
|
|
148
|
+
<CenteredWrapper>
|
|
149
|
+
<ProgressCircle
|
|
150
|
+
isIndeterminate
|
|
151
|
+
aria-label={state.collection.size > 0 ? stringFormatter.format('loadingMore') : stringFormatter.format('loading')} />
|
|
152
|
+
</CenteredWrapper>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function EmptyState() {
|
|
157
|
+
let {renderEmptyState} = useCardViewContext();
|
|
158
|
+
let emptyState = renderEmptyState ? renderEmptyState() : null;
|
|
159
|
+
if (emptyState == null) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<CenteredWrapper>
|
|
165
|
+
{emptyState}
|
|
166
|
+
</CenteredWrapper>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
166
170
|
function CenteredWrapper({children}) {
|
|
167
171
|
let {state} = useCardViewContext();
|
|
168
172
|
return (
|
|
@@ -185,8 +189,8 @@ function InternalCard(props) {
|
|
|
185
189
|
let {state, cardOrientation, isQuiet, layout} = useCardViewContext();
|
|
186
190
|
|
|
187
191
|
let layoutType = layout.layoutType;
|
|
188
|
-
let rowRef = useRef();
|
|
189
|
-
let cellRef = useRef<DOMRefValue<HTMLDivElement>>();
|
|
192
|
+
let rowRef = useRef(undefined);
|
|
193
|
+
let cellRef = useRef<DOMRefValue<HTMLDivElement>>(undefined);
|
|
190
194
|
let unwrappedRef = useUnwrapDOMRef(cellRef);
|
|
191
195
|
|
|
192
196
|
let {rowProps: gridRowProps} = useGridRow({
|
package/src/GridLayout.tsx
CHANGED
|
@@ -130,41 +130,6 @@ export class GridLayout<T> extends BaseLayout<T> {
|
|
|
130
130
|
);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
getVisibleLayoutInfos(rect) {
|
|
134
|
-
let res: LayoutInfo[] = [];
|
|
135
|
-
let numItems = this.collection.size;
|
|
136
|
-
if (numItems <= 0 || !this.itemSize) {
|
|
137
|
-
// If there aren't any items in the collection, we are in a loader/placeholder state. Return those layoutInfos as
|
|
138
|
-
// the currently visible items
|
|
139
|
-
if (this.layoutInfos.size > 0) {
|
|
140
|
-
for (let layoutInfo of this.layoutInfos.values()) {
|
|
141
|
-
if (this.isVisible(layoutInfo, rect)) {
|
|
142
|
-
res.push(layoutInfo);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
} else {
|
|
147
|
-
// The approach from v2 uses indexes where other v3 layouts iterate through every node/root node. This feels more efficient
|
|
148
|
-
let firstVisibleItem = this.getIndexAtPoint(rect.x, rect.y);
|
|
149
|
-
let lastVisibleItem = this.getIndexAtPoint(rect.maxX, rect.maxY);
|
|
150
|
-
for (let index = firstVisibleItem; index <= lastVisibleItem; index++) {
|
|
151
|
-
let keyFromIndex = this.collection.rows[index].key;
|
|
152
|
-
let layoutInfo = this.layoutInfos.get(keyFromIndex);
|
|
153
|
-
if (layoutInfo && this.isVisible(layoutInfo, rect)) {
|
|
154
|
-
res.push(layoutInfo);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Check if loader is in view and add to res if so
|
|
159
|
-
let loader = this.layoutInfos.get('loader');
|
|
160
|
-
if (loader && this.isVisible(loader, rect)) {
|
|
161
|
-
res.push(loader);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return res;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
133
|
buildCollection() {
|
|
169
134
|
let visibleWidth = this.virtualizer.visibleRect.width;
|
|
170
135
|
let visibleHeight = this.virtualizer.visibleRect.height;
|
package/src/WaterfallLayout.tsx
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import {BaseLayout, BaseLayoutOptions} from './BaseLayout';
|
|
14
14
|
import {getChildNodes, getFirstItem} from '@react-stately/collections';
|
|
15
15
|
import {InvalidationContext, LayoutInfo, Rect, Size} from '@react-stately/virtualizer';
|
|
16
|
-
import {Key, KeyboardDelegate
|
|
16
|
+
import {Key, KeyboardDelegate} from '@react-types/shared';
|
|
17
17
|
|
|
18
18
|
export interface WaterfallLayoutOptions extends BaseLayoutOptions {
|
|
19
19
|
/**
|
|
@@ -69,7 +69,7 @@ export class WaterfallLayout<T> extends BaseLayout<T> implements KeyboardDelegat
|
|
|
69
69
|
return 'waterfall';
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
buildCollection(invalidationContext: InvalidationContext
|
|
72
|
+
buildCollection(invalidationContext: InvalidationContext) {
|
|
73
73
|
// Compute the number of columns needed to display the content
|
|
74
74
|
let visibleWidth = this.virtualizer.visibleRect.width;
|
|
75
75
|
let availableWidth = visibleWidth - this.margin * 2;
|