diff --git a/docs/resources/cart/LinesAdd.md b/docs/resources/cart/LinesAdd.md
index 85ad4842ee..a5ed611b1e 100644
--- a/docs/resources/cart/LinesAdd.md
+++ b/docs/resources/cart/LinesAdd.md
@@ -1,17 +1,17 @@
# LinesAdd
-The `LinesAdd` cart resource is a full-stack component that provides a set of utilities to facilitate adding line(s) to the cart. It also provides a set of hooks to help you handle optimistic and pending UI.
+The `LinesAdd` cart resource is a full-stack component that provides a set of utilities to add line(s) to the cart. It also provides a set of hooks to help you handle optimistic and pending UI.
## `LinesAddForm`
A Remix `fetcher.Form` that adds a set of line(s) to the cart. This form mutates the cart via the [cartLinesAdd](https://shopify.dev/api/storefront/2022-10/mutations/cartLinesAdd) mutation and provides
`error`, `state` and `event` instrumentation for analytics.
-| Prop | Type | Description |
-| ------------ | ----------------------- | --------------------------------------------------- | --------------------------- | ------------------------------------------------------------------------------ |
-| `lines` | `{quantity, variant}[]` | `lines items to add to the cart` |
-| `onSuccess?` | `(event) => void` | `A callback that runs after every successful event` |
-| `children` | `({ state: 'idle' | 'submitting' | 'loading'; error: string})` | `A render prop that provides the state and errors for the current submission.` |
+| Prop | Type | Description |
+| ------------ | ---------------------------------------------------------------- | ------------------------------------------------------------------------------ |
+| `lines` | `{quantity, variant}[]` | `lines items to add to the cart` |
+| `onSuccess?` | `(event) => void` | `A callback that runs after every successful event` |
+| `children` | `({ state: 'idle' or 'submitting' or 'loading'; error: string})` | `A render prop that provides the state and errors for the current submission.` |
Basic use:
@@ -47,7 +47,6 @@ function AddToCartButton({selectedVariant, quantity}) {
]}
onSuccess={(event) => {
navigator.sendBeacon('/events', JSON.stringify(event))
- toggleNotification()
}}
>
{(state, error) => (
@@ -83,15 +82,38 @@ const {linesAdd, linesAdding, linesAddingFetcher} = useLinesAdd(onSuccess);
| :----------- | :---------------- | :-------------------------------------------------- |
| `onSuccess?` | `(event) => void` | `A callback that runs after every successful event` |
-Example use
+Example use: reacting to add to cart event
+
+```jsx
+// Toggle a cart drawer when adding to cart
+function Layout() {
+ const {linesAdding} = useLinesAdd();
+ const [drawer, setDrawer] = useState(false);
+
+ useEffect(() => {
+ if (drawer || !linesAdding) return;
+ setDrawer(true);
+ }, [linesAdding, drawer, setDrawer]);
+
+ return (
+
+
+
+
+ );
+}
+```
+
+Example use: programmatic add to cart
```jsx
-// A hook that adds a free gift variant to the cart, if there are 3 items in the cart
+// A hook that programmatically adds a free gift variant to the cart,
+// if there are 3 or more items in the cart
function useAddFreeGift({cart}) {
const {linesAdd, linesAdding} = useLinesAdd();
const giftInCart = cart.lines...
const freeGiftProductVariant = ...
- const shouldAddGift = !linesAdding && !giftInCart && cart.lines.edges.length !== 3;
+ const shouldAddGift = !linesAdding && !giftInCart && cart.lines.edges.length >= 3;
useEffect(() => {
if (!shouldAddGift) return;
diff --git a/docs/resources/cart/LinesRemove.md b/docs/resources/cart/LinesRemove.md
new file mode 100644
index 0000000000..926a4b4127
--- /dev/null
+++ b/docs/resources/cart/LinesRemove.md
@@ -0,0 +1,171 @@
+# LinesRemove
+
+The `LinesRemove` cart resource is a full-stack component that provides a set of utilities to remove line(s) from the cart. It also provides a set of hooks to help you handle optimistic and pending UI.
+
+## `LinesRemoveForm`
+
+A Remix `fetcher.Form` that removes a set of line(s) from the cart. This form mutates the cart via the [cartLinesRemove](https://shopify.dev/api/storefront/2022-10/mutations/cartLinesRemove) mutation and provides
+`error`, `state` and `event` instrumentation for analytics.
+
+| Prop | Type | Description |
+| :----------- | :--------------------------------------------------------------- | :----------------------------------------------------------------------------- |
+| `lineIds` | `['lineId..]` | `line ids to remove from the cart` |
+| `onSuccess?` | `(event) => void` | `A callback that runs after every successful event` |
+| `children` | `({ state: 'idle' or 'submitting' or 'loading'; error: string})` | `A render prop that provides the state and errors for the current submission.` |
+
+Basic use:
+
+```jsx
+function RemoveFromCart({lindeIds}) {
+ return (
+
+ {(state, error) => }
+
+ );
+}
+```
+
+Advanced use:
+
+```jsx
+// Advanced example
+function RemoveFromCart({lindeIds}) {
+ return (
+ {
+ navigator.sendBeacon('/events', JSON.stringify(event))
+ }}
+ >
+ {(state, error) => (
+
+ {error ?
{error}
}
+ )}
+
+ )
+}
+```
+
+## `useLinesRemove`
+
+This hook provides a programmatic way to remove line(s) from the cart;
+
+Hook signature
+
+```jsx
+function onSuccess(event) {
+ console.log('lines removed');
+}
+
+const {linesRemove, linesRemoving, linesRemoveFetcher} =
+ useLinesRemove(onSuccess);
+```
+
+| Action | Description |
+| :------------------- | :--------------------------------------------------------------------------------------------------------- |
+| `linesRemove` | A utility that submits the lines remove mutation via fetcher.submit() |
+| `linesRemoving` | The lines being submitted. If the fetcher is idle it will be null. Useful for handling optimistic updates. |
+| `linesRemoveFetcher` | The Remix `fetcher` handling the current form submission |
+
+| Prop | Type | Description |
+| :----------- | :---------------- | :-------------------------------------------------- |
+| `onSuccess?` | `(event) => void` | `A callback that runs after every successful event` |
+
+Example use
+
+```jsx
+// A hook that removes a free gift variant from the cart, if there are less than 3 items in the cart
+function useRemoveFreeGift({cart}) {
+ const {linesRemove, linesRemoving} = useLinesRemove();
+ const freeGiftLineId = cart.lines.filter;
+ const shouldRemoveGift =
+ !linesRemoving && freeGiftLineId && cart.lines.edges.length < 3;
+
+ useEffect(() => {
+ if (!shouldRemoveGift) return;
+ linesRemove({
+ lineIds: [freeGiftLineId],
+ });
+ }, [shouldRemoveGift, freeGiftLineId]);
+}
+```
+
+## `useOptimisticLineRemove`
+
+A utility hook to easily implement optimistic UI when a specific line is being removed.
+
+Hook signature
+
+```jsx
+const {optimisticLineRemove, linesRemoving} = useOptimisticLineRemove(lines);
+```
+
+| Action | Description |
+| :--------------------- | :--------------------------------------------------------------------------------------------------------- |
+| `optimisticLineRemove` | A boolean indicating if the line is being removed |
+| `linesRemoving` | The lines being submitted. If the fetcher is idle it will be null. Useful for handling optimistic updates. |
+
+Example use
+
+```jsx
+function CartLineItem({line}) {
+ const {optimisticLineRemove} = useOptimisticLineRemove(line);
+ const {id: lineId, merchandise} = line;
+
+ return (
+
+
{{merchandise.product.title}}
+
+ ...
+
+ );
+}
+```
+
+## `useOptimisticLinesRemove`
+
+A utility hook to easily implement optimistic UI when a any cart line is being removed.
+
+Hook signature
+
+```jsx
+const {optimisticLastLineRemove, linesRemoving} =
+ useOptimisticLinesRemove(lines);
+```
+
+| Action | Description |
+| :------------------------- | :--------------------------------------------------------------------------------------------------------- |
+| `optimisticLastLineRemove` | A boolean indicating that the last line in cart is being removed |
+| `linesRemoving` | The lines being submitted. If the fetcher is idle it will be null. Useful for handling optimistic updates. |
+
+Example use
+
+```jsx
+function Cart({cart}) {
+ const {lines} = cart;
+ const {optimisticLastLineRemove} = useOptimisticLinesRemove(lines);
+
+ // optimistically show an empty cart if removing the last line
+ const cartEmpty = lines.length === 0 || optimisticLastLineRemove;
+
+ return (
+