Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement BaseCard #529

Closed
3 tasks
MisRob opened this issue Jan 24, 2024 · 2 comments · Fixed by #625
Closed
3 tasks

Implement BaseCard #529

MisRob opened this issue Jan 24, 2024 · 2 comments · Fixed by #625

Comments

@MisRob
Copy link
Member

MisRob commented Jan 24, 2024

Blocks

Summary

Implement BaseCard, a helper private component that will be used by the public KCard component. Please see #528 first.

Markup requirements

  • The outermost element is <li>
  • <a> (generated from the <router-link>) is placed inside the heading element and the title is inside the link
  • Contains the heading element and it is placed above all its siblings that will be passed down from KCard via the default slot
<li>
  <h[2-6]>
    <a href="/resource">Resource</a>
  </h[2-6]>
  <slot>
</li>

This ensures that no matter of how we refactor the parent component KCard in the future, during the process we won't mingle new updates with basic a11y criteria related to card list, heading placement, and link that need to be satisfied under all circumstances. In a way, one of the functions of the BaseCard is to 'protect' them.

Style requirements

  • Doesn't have set width/height (this will be controlled from KCard or card grid)
  • Even though the whole card is not wrapped in the link, the whole card area is clickable and has the pointer cursor style
  • Has focus ring on focus utilizing our $coreOutline (see "Keyboard navigation"). Even though the whole card is not wrapped in the link, the focus ring still needs to show around the whole card area.
  • Even though the whole area is clickable, text content is still selectable
  • Has shadow styles
  • Has the same hover style as the one used for the current Kolibri cards
  • Has rounded corners

Visit the Figma designs to retrieve some of the related CSS styles.

Interface

Props

Name Description Type Required Default
to Router-link object that enables user navigation to the intended route. Object true -
title Sets the value of the title text. A simpler alternative to the title slot. String false null
titleLines A number of lines a title text is truncated to. Number false 2
headingLevel A level of the heading element (<h2>-<h6>) wrapping a title text. Supported values: 2-6. Number true -

Slots

Name Description
default Contents of the card except its title.
title The title contents. It should not contain a heading element. An alternative to the title prop.

Events

Name Description
focus Emitted when the card element has received focus.
hover Emitted when the mouse pointer enters or leaves the card element

Acceptance criteria

  • Conforms fully to the specification above
  • Is not exposed publicly and doesn't have a documentation page
  • Contains validation to check that title prop or slot has been used, throwing an error if neither is provided

Guidance

Using these particular techniques is not required, just a few tips that may help:

Existing code

In kolibri/kolibri/plugins/learn/assets/src/views/cards/, you can find lots of code for current cards in Kolibri. I wouldn't recommend it when it comes to markup and architecture since our first cards aren't very consistent and accessible (KCard is here to solve that). However, it may be useful for pulling out pieces of logic that would still be useful rather then re-implementing it. One example wold be existing styles for :hover state in CardLink.

Hover and focus

:focus-within may be helpful for implementing focus and hover styles around the whole card area

Selectable textual content

To make textual content selectable within the whole clickable card area, "Inclusive Components: Cards ("The redundant click event" section) offers a technique that may serve as inspiration for a Vue based solution:

We need to detect how long the user is taking between mousedown and mouseup and suppress the event if it's "likely to be selecting text" territory.

const cards = document.querySelectorAll('.card');  
Array.prototype.forEach.call(cards, card => {  
    let down, up, link = card.querySelector('h2 a');
    card.onmousedown = () => down = +new Date();
    card.onmouseup = () => {
        up = +new Date();
        if ((up - down) < 200) {
            link.click();
        }
    }
});
@EshaanAgg
Copy link
Contributor

Hi! I would like to work on this issue if this is available to external contributors.

@MisRob
Copy link
Member Author

MisRob commented Jan 27, 2024

Hi @EshaanAgg, thank you - there is already a team member who will work on this (and other issues from this group)

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

Successfully merging a pull request may close this issue.

3 participants