#Responsive styles

1 messages · Page 1 of 1 (latest)

grave prairie
#

How can I add dynamic, responsive styles in the editor? For example, if I choose the tablet screen option in the editor, how can I then add styles specifically for the tablet screen? What do you think?

tiny dust
#

Puck doesn't need anything special here. So just use media queries if using CSS, or Tailwind viewport modifiers if using Tailwind, etc

grave prairie
#

I am using CSS and have added media queries, but for a component that appears on two different pages, each page needs separate responsive styles. How can I resolve this case?

tiny dust
#

However you would solve it if Puck wasn't involved - easiest to add a separate component with its own styles. You could also create a separate page with its own styles and import your Puck instance as a component.

remote dew
#

Late to this show. Im trying out what @tiny dust here says to use tailwind's viewport modifiers. The problem here is that tailwind automatically strips (or never includes) unused classes, keeping the bundle small. Tailwind of course does not know what dynamic html is inserted into the view, it could never know.

You can easily get proof of this problem if you add classes to the safelist https://tailwindcss.com/docs/content-configuration#safelisting-classes

You see then that responsive-ness starts to work.

Puck seems to be an amazing tool, but for me it breaks a bit on "how to actually build responsive webpages", or at least a bit of guidance on best practices that work.

This is what Im trying to do in the editor, see "textAlign". But Im getting stuck with the styles not being seen by tailwind, so they are stripped sadly.

Configuring the content sources for your project.

remote dew
#

What helped here is to build 'mobile first' and then take a break point like "md" for which you can define all the styles in a placeholders file (anywhere defined because tailwind uses it to to see which classes to keep).

Generated with ChatGPT:

// Just export a string that includes all the classes you want Tailwind to preserve:
module.exports = `
  /* Text alignment (md:) */
  md:text-left
  md:text-center
  md:text-right
  md:text-justify
  md:text-start
  md:text-end

  /* Flexbox (md:) */
  md:flex
  md:inline-flex
  md:flex-row
  md:flex-row-reverse
  md:flex-col
  md:flex-col-reverse
  md:flex-wrap
  md:flex-wrap-reverse
  md:flex-nowrap
  md:justify-start
  md:justify-center
  md:justify-end
  md:justify-between
  md:justify-around
  md:justify-evenly
  md:items-start
  md:items-center
  md:items-end
  md:items-baseline
  md:items-stretch
  md:content-start
  md:content-center
  md:content-end
  md:content-between
  md:content-around
  md:content-evenly
  md:self-auto
  md:self-start
  md:self-center
  md:self-end
  md:self-stretch
  md:grow
  md:grow-0
  md:shrink
  md:shrink-0

  /* Grid (md:) */
  md:grid
  md:inline-grid
  md:grid-cols-1
  md:grid-cols-2
  md:grid-cols-3
  md:grid-cols-4
  md:grid-cols-5
  md:grid-cols-6
  md:grid-cols-7
  md:grid-cols-8
  md:grid-cols-9
  md:grid-cols-10
  md:grid-cols-11
  md:grid-cols-12
  md:grid-rows-1
  md:grid-rows-2
  md:grid-rows-3
  md:grid-rows-4
  md:grid-rows-5
  md:grid-rows-6
  md:gap-0
  md:gap-1
  md:gap-2
  md:gap-3
  md:gap-4
  md:gap-5
  md:gap-6
  md:gap-7
  md:gap-8
  md:gap-9
  md:gap-10

  /* place-content (md:) */
  md:place-content-center
  md:place-content-start
  md:place-content-end
  md:place-content-between
  md:place-content-around
  md:place-content-evenly
  md:place-content-stretch
`;

tiny dust
#

CC @sly jacinth - could be some good content

remote dew
#

Ah I tried without the iframe, but "problem" is that tailwind optimizes and purges all classes that you haven't defined anywhere. So, it's not the iframe, it's tailwind stripping everything it didn't "see". And since I'm dynamically creating the classes, it hasnt seen them anywhere.

For example, this is my custom textAlign field, so you can select different text-aligns based on the tailwind breakpoints. You see, it never sees md:text-center anywhere as it hasnt been stated. Therefore in combination with the file above (with all those classes stated), it does work.

const typographyFields = [
  textAlign: {
    type: "custom",
    label: "Label Example",
    options: [
      { label: "Left", value: "text-left" },
      { label: "Center", value: "text-center" },
      { label: "Right", value: "text-right" },
    ],
    defaultValue: {
      default: "text-left",
      md: "text-right",
    },
    render: ({ field, onChange, value }) => {
      const breakpoints = ["default", "md"];

      return (
        <div className="responsive-field">
          {breakpoints.map((breakpoint) => (
            <Box key={breakpoint}>
              <FieldLabel key={breakpoint} label={breakpoint ? `${breakpoint.toUpperCase()}:` : "Default:"} />
              <AutoField
                field={{ type: "radio", options: field.options }}
                value={value?.[breakpoint] || ""}
                onChange={(v) => {
                  onChange({
                    ...(typeof value === "string" ? {} : value),
                    [breakpoint]: v,
                  })}
                }
              />
            </Box>
          ))}
        </div>
      )
    }
  },
]
tiny dust
#

Ah right

#

Can you whitelist everything for the editor and then rely on the detection for rendering the final page?

remote dew
#

Let me see. I won't see how that could work, you would need to preprocess a build version of what comes out of Puck when rendered. In theory you could do it, but I don't see that path yet. Hmm.

Im using nextjs, so for it to work correctly you would pre-build those pages (server side components without any interaction possible), and then not include the whitelist file in the final build (somehow)

tiny dust
#

We need to spend a bit more time on this so let us know what you discover

#

in the mean time, I think whitelisting all available options is the easiest way to work around it

remote dew
#

Yea will do for now, I probably also wont need ALL of the options. Just a default (mobile first) and then exceptions starting the md or lg breakpoint works for me.

Maybe Im trying to make a bit too customizable components within Puck, I could also predefine pretty Sections which would work on all viewport sizes. But it seemed like a cool thing to support with these breakpoints, it then resembles how things like Elementor, Builder.io, Divi and such. But all those builders have short comings too, so it's a lot of fun to start having more control!

Thanks for the input (and the amazing work that went into this project!).

tiny dust
#

Wonderful! Excited to see what you do 🙂

remote dew
#

Ill be sharing something for sure! Need to make some time in between full-time working but this little pet project gets me going for sure

rugged cargo
#

Hello, I'm testing the Grid component ... I want to play with gridTemplateColumns : 1fr 1fr 1fr in desktop and i want it to be set as only 1fr in mobile and tablet ... Is there a way I can do it easily ?