Skip to content

Add peer-* variants - #4556

Merged
adamwathan merged 1 commit into
masterfrom
add-peer-variant
Jun 4, 2021
Merged

Add peer-* variants#4556
adamwathan merged 1 commit into
masterfrom
add-peer-variant

Conversation

@adamwathan

Copy link
Copy Markdown
Member

This PR adds new peer-* variants to the JIT engine that behave much like the group-* variants, but target sibling elements instead of parent elements.

This is useful for things like targeting siblings when a checkbox is checked, doing things like floating labels, etc.

<label>
  <input type="checkbox" class="peer sr-only">
  <span class="h-4 w-4 bg-gray-200 peer-checked:bg-blue-500">
  <!-- ... -->
</label>

This generates CSS like this:

.peer:checked ~ .peer-checked\:bg-blue-500 {
  background-color: blue;
}

So you can only do it based on previous siblings, which you are probably already used to because of how CSS works.

@inopinatus

Copy link
Copy Markdown

Will a peer grouping work as well? Sometimes a child element needs to know that a parent was selected by a sibling combinator.

I have a couple of scrappy plugins I used for this already, see https://play.tailwindcss.com/BvQpg9QWEe
(this example uses adjacency, but it's just + instead of ~)

@adamwathan

Copy link
Copy Markdown
Member Author

@inopinatus No easy way to do that with just this + the existing group API but it's something we could explore as an improvement down the road for sure, either by finding ways to make this stuff composable or just adding a dedicated new variant type, maybe something like:

<input class="peer" type="checkbox">
<div class="group">
  <span class="group-peer-checked:bg-blue-500 ...">
    <!-- ... -->
  </span>
</div>

@seb-jean

Copy link
Copy Markdown
Contributor

I would be interested in having a new variant type group-peer-checked :)

@wolthers

wolthers commented Jul 5, 2022

Copy link
Copy Markdown

@adamwathan @seb-jean: This can be solved with a custom plugin:

tailwind.config.js

const plugin = require("tailwindcss/plugin");

/**
 * @type {import('tailwindcss').Config}
 */
module.exports = {
  ....
  plugins: [
    plugin(function groupPeer({ addVariant }) {
      let pseudoVariants = [
        //... Any other pseudo variants you want to support. See https://github.com/tailwindlabs/tailwindcss/blob/6729524185b48c9e25af62fc2372911d66e7d1f0/src/corePlugins.js#L78
        "checked",
      ].map((variant) =>
        Array.isArray(variant) ? variant : [variant, `&:${variant}`],
      );

      for (let [variantName, state] of pseudoVariants) {
        addVariant(`group-peer-${variantName}`, (ctx) => {
          let result = typeof state === "function" ? state(ctx) : state;
          return result.replace(/&(\S+)/, ":merge(.peer)$1 ~ .group &");
        });
      }
    }),
  ],
};

Implementation:

<div>
  <input class="peer" type="radio" />
  <label class="group">
    <span class="group-peer-checked:hidden"></span>
    <span class="hidden group-peer-checked:block"></span>
    Some label
  </label>
</div>

@shuaixr

shuaixr commented Nov 14, 2022

Copy link
Copy Markdown

@adamwathan @seb-jean @wolthers I used some black magic🤣

<input class="peer" type="checkbox">
<div class="[&_.some-text]:peer-checked:bg-blue-500">
  <span class="other-text">
    other-text
  </span>
  <span class="some-text">
    some-text
  </span>
</div>

OR

<input class="peer" type="checkbox">
<div class="group">
  <span class="peer-checked:[.group_&]:bg-blue-500">
    some-text
  </span>
</div>

@adamwathan
adamwathan deleted the add-peer-variant branch May 15, 2023 16:50
@Ananta-Paul

Copy link
Copy Markdown

@adamwathan @seb-jean @wolthers if the input something like:

<div>
<input class="peer" type="checkbox">
</div>
<div class="group">
  <span class="group-peer-checked:bg-blue-500 ...">
    <!-- ... -->
  </span>
</div>

then how we can achive that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants