Skip to content

Commit

Permalink
optional animation config
Browse files Browse the repository at this point in the history
  • Loading branch information
Shane Osbourne committed Oct 13, 2024
1 parent 4644d3b commit 62102e5
Show file tree
Hide file tree
Showing 13 changed files with 141 additions and 59 deletions.
11 changes: 9 additions & 2 deletions packages/special-pages/messages/new-tab/examples/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@ const privacyStatsData = {
/**
* @type {import("../../../types/new-tab").StatsConfig}
*/
const statsConfig = {
const minimumConfig = {
expansion: "expanded"
}

/**
* @type {import("../../../types/new-tab").StatsConfig}
*/
const withAnimation = {
expansion: "expanded",
animation: { kind: "none" }
animation: { kind: "view-transitions" }
}

export {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "FavoritesConfig",
"type": "object",
"required": ["expansion", "animation"],
"required": ["expansion"],
"properties": {
"expansion": {"$ref": "./expansion.json"},
"animation": {"$ref": "./animation.json"}
"expansion": { "$ref": "./expansion.json" },
"animation": { "$ref": "./animation.json" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "StatsConfig",
"type": "object",
"required": ["expansion", "animation"],
"required": ["expansion"],
"properties": {
"expansion": {"$ref": "./expansion.json"},
"animation": {"$ref": "./animation.json"}
Expand Down
16 changes: 16 additions & 0 deletions packages/special-pages/pages/new-tab/app/components/Examples.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@ export const mainExamples = {
<MockFavoritesProvider data={{favorites: favorites.many.favorites.slice(0, 7)}}><FavoritesConsumer /></MockFavoritesProvider>
)
},
'favorites.few.7.auto-animate': {
factory: () => (
<MockFavoritesProvider
data={{favorites: favorites.many.favorites.slice(0, 7)}}
config={{expansion: "expanded", animation: { kind: "auto-animate" }}}
><FavoritesConsumer /></MockFavoritesProvider>
)
},
'favorites.few.7.view-transitions': {
factory: () => (
<MockFavoritesProvider
data={{favorites: favorites.many.favorites.slice(0, 7)}}
config={{expansion: "expanded", animation: { kind: "view-transitions" }}}
><FavoritesConsumer /></MockFavoritesProvider>
)
},
'favorites.few.6': {
factory: () => (
<MockFavoritesProvider data={{favorites: favorites.many.favorites.slice(0, 6)}}><FavoritesConsumer /></MockFavoritesProvider>
Expand Down
70 changes: 64 additions & 6 deletions packages/special-pages/pages/new-tab/app/favorites/Favorites.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { h } from 'preact'
import cn from 'classnames'
import { useAutoAnimate } from '@formkit/auto-animate/preact'

import { useVisibility } from '../widget-list/widget-config.provider.js'
import styles from './Favorites.module.css'
import { useContext, useId, useMemo } from 'preact/hooks'
import { useContext, useId, useMemo, useCallback } from 'preact/hooks'
import { TileMemo } from './Tile.js'
import { FavoritesContext, FavoritesDispatchContext, FavoritesProvider } from './FavoritesProvider.js'
import { FavoritesContext, FavoritesProvider } from './FavoritesProvider.js'
import { useGridState } from './FavouritesGrid.js'
import { memo } from 'preact/compat'
import { Chevron } from '../components/Chevron.js'
import { useTypedTranslation } from '../types.js'
import { viewTransition } from '../utils.js'

/**
* @typedef {import('../../../../types/new-tab').Expansion} Expansion
* @typedef {import('../../../../types/new-tab').Animation} Animation
* @typedef {import('../../../../types/new-tab').Favorite} Favorite
* @typedef {import('../../../../types/new-tab').FavoritesData} FavoritesData
* @typedef {import('../../../../types/new-tab').FavoritesConfig} FavoritesConfig
Expand All @@ -23,9 +27,63 @@ import { useTypedTranslation } from '../types.js'
* @param {(list: Favorite[]) => void} props.listDidReOrder
* @param {Expansion} props.expansion
* @param {() => void} props.toggle
* @param {Animation['kind']} [props.animation] - optionally configure animations
*/
export function Favorites ({ favorites, listDidReOrder, expansion, toggle, animation }) {
if (animation === 'auto-animate') {
return <WithAutoAnimate favorites={favorites} listDidReOrder={listDidReOrder} expansion={expansion} toggle={toggle} />
}
if (animation === 'view-transitions') {
return <WithViewTransitions favorites={favorites} listDidReOrder={listDidReOrder} expansion={expansion} toggle={toggle} />
}

// no animations
return <FavoritesConfigured
favorites={favorites}
expansion={expansion}
toggle={toggle}
listDidReOrder={listDidReOrder}
animateItems={'none'}
/>
}

/**
* @param {object} props
* @param {Favorite[]} props.favorites
* @param {(list: Favorite[]) => void} props.listDidReOrder
* @param {Expansion} props.expansion
* @param {() => void} props.toggle
*/
export function WithAutoAnimate (props) {
const [ref] = useAutoAnimate()
return <FavoritesConfigured {...props} gridRef={ref} animateItems={'none'} />
}

/**
* @param {object} props
* @param {Favorite[]} props.favorites
* @param {(list: Favorite[]) => void} props.listDidReOrder
* @param {Expansion} props.expansion
* @param {() => void} props.toggle
*/
export function WithViewTransitions (props) {
const willToggle = useCallback(() => {
viewTransition(props.toggle)
}, [props.toggle])
return <FavoritesConfigured {...props} toggle={willToggle} animateItems={'view-transitions'} />
}

/**
* @param {object} props
* @param {import("preact").Ref<any>} [props.gridRef]
* @param {Favorite[]} props.favorites
* @param {(list: Favorite[]) => void} props.listDidReOrder
* @param {Expansion} props.expansion
* @param {Animation['kind']} props.animateItems
* @param {() => void} props.toggle
*/
export function Favorites ({ favorites, listDidReOrder, expansion, toggle }) {
useGridState(favorites, listDidReOrder)
export function FavoritesConfigured ({ gridRef, favorites, listDidReOrder, expansion, toggle, animateItems }) {
useGridState(favorites, listDidReOrder, animateItems)

// todo: does this need to be dynamic for smaller screens?
const ROW_CAPACITY = 6
Expand Down Expand Up @@ -63,6 +121,7 @@ export function Favorites ({ favorites, listDidReOrder, expansion, toggle }) {
<div
class={styles.grid}
id={WIDGET_ID}
ref={gridRef}
>
{items.slice(0, expansion === 'expanded' ? undefined : ROW_CAPACITY)}
</div>
Expand Down Expand Up @@ -175,12 +234,11 @@ export function FavoritesCustomized () {
export function FavoritesConsumer () {
const { state, toggle, listDidReOrder } = useContext(FavoritesContext)
if (state.status === 'ready') {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const send = useContext(FavoritesDispatchContext)
return (
<Favorites
favorites={state.data.favorites}
expansion={state.config.expansion}
animation={state.config.animation?.kind}
listDidReOrder={listDidReOrder}
toggle={toggle}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(64px, 1fr));
align-items: start;
grid-column-gap: 24px;
grid-row-gap: 8px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { flushSync } from 'preact/compat'
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter'
import { extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge'
import { reorderWithEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/util/reorder-with-edge'
import { viewTransition } from '../utils.js'

/**
* @typedef {import('../../../../types/new-tab').FavoritesData} FavoritesData
* @typedef {import('../../../../types/new-tab').Favorite} Favorite
* @typedef {import('../../../../types/new-tab').Animation} Animation
* @typedef {import('../../../../types/new-tab').FavoritesConfig} FavoritesConfig
*/

Expand All @@ -22,8 +24,9 @@ export const InstanceIdContext = createContext(getInstanceId())
/**
* @param {Favorite[]} favorites
* @param {(list: Favorite[]) => void} setFavorites
* @param {Animation['kind']} animation
*/
export function useGridState (favorites, setFavorites) {
export function useGridState (favorites, setFavorites, animation) {
const instanceId = useContext(InstanceIdContext)
useEffect(() => {
return monitorForElements({
Expand All @@ -50,33 +53,24 @@ export function useGridState (favorites, setFavorites) {
const to = favorites.findIndex(item => item.data === destinationSrc)

const closestEdgeOfTarget = extractClosestEdge(target.data)
const reorderedList = reorderWithEdge({
list: favorites,
startIndex: from,
indexOfTarget: to,
closestEdgeOfTarget,
axis: 'horizontal'
})

if ('startViewTransition' in document && typeof document.startViewTransition === 'function') {
document.startViewTransition(() => {
if (animation === 'view-transitions') {
viewTransition(() => {
flushSync(() => {
setFavorites(
reorderWithEdge({
list: favorites,
startIndex: from,
indexOfTarget: to,
closestEdgeOfTarget,
axis: 'horizontal'
})
)
setFavorites(reorderedList)
})
})
} else {
setFavorites(
reorderWithEdge({
list: favorites,
startIndex: from,
indexOfTarget: to,
closestEdgeOfTarget,
axis: 'horizontal'
})
)
setFavorites(reorderedList)
}
}
})
}, [instanceId, favorites])
}, [instanceId, favorites, animation])
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ function getInstanceId () {
}

/** @type {FavoritesConfig} */
const DEFAULT_CONFIG = { expansion: 'expanded', animation: {kind: "none"} }
const DEFAULT_CONFIG = {
expansion: 'expanded'
}

/**
* @param {object} props
Expand All @@ -28,9 +30,10 @@ const DEFAULT_CONFIG = { expansion: 'expanded', animation: {kind: "none"} }
* @param {FavoritesConfig} [props.config]
*/
export function MockFavoritesProvider ({
data = favorites.many,
config = DEFAULT_CONFIG,
children }) {
data = favorites.many,
config = DEFAULT_CONFIG,
children
}) {
const { isReducedMotion } = useEnv()

const [instanceId] = useState(getInstanceId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { useContext, useState, useId, useCallback } from 'preact/hooks'
import { PrivacyStatsContext, PrivacyStatsProvider } from './PrivacyStatsProvider.js'
import { useVisibility } from '../widget-list/widget-config.provider.js'
import { Chevron } from '../components/Chevron.js'
import { useAutoAnimate } from "@formkit/auto-animate/preact";
import { viewTransition } from "../utils.js";
import { useAutoAnimate } from '@formkit/auto-animate/preact'
import { viewTransition } from '../utils.js'

/**
* @typedef {import('../../../../types/new-tab').TrackerCompany} TrackerCompany
Expand All @@ -23,15 +23,14 @@ import { viewTransition } from "../utils.js";
* @param {Expansion} props.expansion
* @param {PrivacyStatsData} props.data
* @param {()=>void} props.toggle
* @param {Animation} props.animation
* @param {Animation['kind']} [props.animation] - optionally configure animations
*/
export function PrivacyStats ({ expansion, data, toggle, animation }) {

if (animation.kind === "auto-animate") {
if (animation === 'auto-animate') {
return <WithAutoAnimate data={data} expansion={expansion} toggle={toggle} />
}

if (animation.kind === "view-transitions") {
if (animation === 'view-transitions') {
return <WithViewTransitions data={data} expansion={expansion} toggle={toggle} />
}

Expand All @@ -45,9 +44,9 @@ export function PrivacyStats ({ expansion, data, toggle, animation }) {
* @param {PrivacyStatsData} props.data
* @param {()=>void} props.toggle
*/
function WithViewTransitions({expansion, data, toggle}) {
function WithViewTransitions ({ expansion, data, toggle }) {
const willToggle = useCallback(() => {
viewTransition(toggle);
viewTransition(toggle)
}, [toggle])
return <PrivacyStatsConfigured expansion={expansion} data={data} toggle={willToggle} />
}
Expand All @@ -58,8 +57,8 @@ function WithViewTransitions({expansion, data, toggle}) {
* @param {PrivacyStatsData} props.data
* @param {()=>void} [props.toggle]
*/
function WithAutoAnimate({expansion, data, toggle}) {
const [ref] = useAutoAnimate({});
function WithAutoAnimate ({ expansion, data, toggle }) {
const [ref] = useAutoAnimate({ duration: 100 })
return <PrivacyStatsConfigured parentRef={ref} expansion={expansion} data={data} toggle={toggle} />
}

Expand All @@ -70,7 +69,7 @@ function WithAutoAnimate({expansion, data, toggle}) {
* @param {PrivacyStatsData} props.data
* @param {()=>void} [props.toggle]
*/
function PrivacyStatsConfigured({ parentRef, expansion, data, toggle }) {
function PrivacyStatsConfigured ({ parentRef, expansion, data, toggle }) {
const expanded = expansion === 'expanded'
const someCompanies = data.trackerCompanies.length > 0

Expand Down Expand Up @@ -161,7 +160,7 @@ export function Body ({ trackerCompanies, id }) {
const [formatter] = useState(() => new Intl.NumberFormat())

const bodyClasses = cn({
[styles.list]: true,
[styles.list]: true
})

return (
Expand Down Expand Up @@ -227,7 +226,7 @@ export function PrivacyStatsConsumer () {
return (
<PrivacyStats
expansion={state.config.expansion}
animation={state.config.animation}
animation={state.config.animation?.kind}
data={state.data}
toggle={toggle}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { reducer } from '../../service.hooks.js'
*/
export function PrivacyStatsMockProvider ({
data = stats.few,
config = { expansion: 'expanded', animation: { kind: "none" } },
config = { expansion: 'expanded', animation: { kind: 'none' } },
ticker = false,
children
}) {
Expand Down Expand Up @@ -59,7 +59,7 @@ export function PrivacyStatsMockProvider ({
}, [state.data?.totalCount, ticker])

const toggle = useCallback(() => {
if (state.status !== 'ready') return console.warn('was not ready');
if (state.status !== 'ready') return console.warn('was not ready')
if (state.config?.expansion === 'expanded') {
send({ kind: 'config', config: { ...state.config, expansion: 'collapsed' } })
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/special-pages/pages/new-tab/app/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function withLog (name, reducer) {
/**
* @param {function} fn
*/
export function viewTransition(fn) {
export function viewTransition (fn) {
if ('startViewTransition' in document && typeof document.startViewTransition === 'function') {
return document.startViewTransition(fn)
}
Expand Down
Loading

0 comments on commit 62102e5

Please sign in to comment.