FollowButton
Follow becomes Following once pressed, and says Unfollow on hover, as the social sites do.
Demo
Rest the pointer on a Following button: it says Unfollow.
Get it
It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.
$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/follow_button.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/follow_button.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/follow_button.qwe
component FollowButtonDemoLive() { state on = false <div.demo-row> <FollowButton on_change={(v) => { on = v }}/> <span.demo-note>{on ? "Following Ada." : "Not following Ada."}</span> </div>}view FollowButtonDemo() = <div.demo-stack> <FollowButtonDemoLive/> <div.demo-row> <FollowButton following={true} name="follow"/> <FollowButton size="sm"/> <FollowButton size="lg" follow="Subscribe" followed="Subscribed" unfollow="Unsubscribe"/> <FollowButton disabled={true}/> </div> <p.demo-note>Rest the pointer on a Following button: it says Unfollow.</p> </div>Source
ui/follow_button.qwe
// FollowButton: Follow, which becomes Following once pressed, and says Unfollow (in// red) while the pointer rests on it or it has the focus, as the social sites do. In// a form it sends `name` while following.//// <FollowButton/>// <FollowButton following={true} name="follow" on_change={(on) => { follow(user, on) }}/>//// following: pressed to start with. labels: follow ("Follow"), following// ("Following"), unfollow ("Unfollow"). name and value ("1"): sent as name=value while// following, in a <form>. size: "sm", "md" (default) or "lg". full: as wide as its// container. The text itself says the state, so screen readers hear "Following" and// the button has no aria-pressed. on_change(following): inside one of your// components, given true or false.import ui/theme.qwe use ui_clslet follow_button_css = css`.ui-follow-button { display: inline-flex; align-items: center; justify-content: center; height: 34px; min-width: 96px; padding: 0 16px; border: 1px solid transparent; border-radius: 999px; background: var(--ui-fg); color: var(--ui-bg); font: 600 14px/1 var(--ui-font); white-space: nowrap; cursor: pointer; transition: background .15s, color .15s, border-color .15s;}.ui-follow-button:hover { background: color-mix(in srgb, var(--ui-fg) 85%, var(--ui-bg)); }.ui-follow-button:focus-visible { outline: none; box-shadow: var(--ui-focus); }.ui-follow-button:disabled { opacity: .55; cursor: not-allowed; }.ui-follow-button-on { background: transparent; color: var(--ui-fg); border-color: var(--ui-border); }.ui-follow-button-on:hover, .ui-follow-button-on:focus-visible { background: var(--ui-danger-soft); color: var(--ui-danger); border-color: color-mix(in srgb, var(--ui-danger) 40%, var(--ui-border)); }.ui-follow-button-labels { display: inline-grid; }.ui-follow-button-labels > span { grid-area: 1 / 1; text-align: center; }.ui-follow-button-un { visibility: hidden; }.ui-follow-button-on:hover .ui-follow-button-un, .ui-follow-button-on:focus-visible .ui-follow-button-un { visibility: visible; }.ui-follow-button-on:hover .ui-follow-button-text, .ui-follow-button-on:focus-visible .ui-follow-button-text { visibility: hidden; }.ui-follow-button-sm { height: 28px; min-width: 80px; padding: 0 12px; font-size: 13px; }.ui-follow-button-lg { height: 42px; min-width: 120px; padding: 0 22px; font-size: 15px; }.ui-follow-button-full { display: flex; width: 100%; }@media (prefers-reduced-motion: reduce) { .ui-follow-button { transition: none; } }`component FollowButton(following: bool = false, follow: str = "Follow", followed: str = "Following", unfollow: str = "Unfollow", name: str? = null, value: str = "1", size: str = "md", full: bool = false, disabled: bool = false, on_change = null, class: str? = null) { style global follow_button_css state on = following <button type="button" class={ui_cls(["ui-follow-button", on && "ui-follow-button-on", size != "md" && `ui-follow-button-${size}`, full && "ui-follow-button-full", class])} disabled={disabled} @click={() => { on = !on on_change && on_change(on) }}> <span.ui-follow-button-labels> <span.ui-follow-button-text>{on ? followed : follow}</span> {on && <span.ui-follow-button-un aria-hidden="true">{unfollow}</span>} </span> {name != null && <input type="hidden" name={name} value={value} disabled={!on}/>} </button>}Related
BookmarkButtonA save-for-later toggle whose bookmark fills when pressed, with or without its label.8 views · 8 downloadsLikeButtonA heart that toggles with a count that follows it, a real toggle for screen readers and forms.5 views · 4 downloadsShareButtonShares a link through the system's share sheet, or copies it where the browser has none, and says which.6 views · 5 downloadsVoteButtonsUp and down votes around a score that follows them, as on a forum, in a column or a row.5 views · 6 downloadsButtonA button, or a link that looks like one: four variants, three tones, three sizes, loading.7 views · 7 downloadsButtonGroupButtons joined edge to edge into one control, or spaced in a row; across or upright.6 views · 6 downloads
Thread
Thread 0 posts
On FollowButton: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.