What makes an element unclickable when using locator(), but clickable when using $()?

I’m trying to automate posting content to Facebook. Assuming you don’t need to login, here is my code:

import { Page } from "npm:puppeteer";

// Initiate
const browser = await puppeteer.launch({
headless: false,
userDataDir: "./user_data",
args: minimal_args.concat(args),
});
const page = await browser.newPage();
await page.goto("https://facebook.com/");

// Create a post
await page.locator("::-p-text(What's on your mind)").click();
await page.keyboard.type(text);

// Click the next button
const nextButtonSelector = '*[aria-label="Next"][role="button"]';
await (await page.$(nextButtonSelector))!.click(); // this works
// await page.locator(nextButtonSelector).click(); // timeout

// Click the post button
await page.locator('*[aria-label="Post"][role="button"]').click();

At the “Click the next button” step, I have to use the Page.$() method, not Page.locator() one. I notice that when no character has been typed in yet, the button is gray out, indicates that it is disabled. I suspect this plays a role in here, but I cannot explain better. The excellent answer in Page.locator() is the recommended way to select and interact with elements. Why does it offer less functionalities than Page.$()? explains the difference between the two, but I don’t know how to apply the knowledge in here.