Class: Shadcn::ScrollArea::Viewport::Component

Inherits:
ApplicationViewComponent show all
Defined in:
app/components/shadcn/scroll_area/viewport/component.rb

Overview

The box that actually scrolls. Native scrollbars are hidden on it — shadcn.css carries the rule Radix injects as a <style> tag (vendor/radix/ui/scroll-area.tsx:266-278), keyed on the slot rather than on a class, so a host cannot switch it off by accident and there is no token for parity_spec to miss.

overflow is inline and per axis, as Radix writes it (:222-223): scroll on an axis with a scrollbar, hidden on one without. It has to be scroll rather than auto — the element must keep its scrollable geometry even when the custom bar is the only thing showing it.

Constant Summary

Constants inherited from ApplicationViewComponent

ApplicationViewComponent::CONTENTS_STYLE, ApplicationViewComponent::VOID_TAGS

Instance Attribute Summary collapse

Attributes inherited from ApplicationViewComponent

#attributes

Instance Method Summary collapse

Methods inherited from ApplicationViewComponent

#css_classes, default_tag, #merged_style, #render_element, #shadcn_t, slot_name, #style_variants, #tag_name

Constructor Details

#initialize(horizontal: false, vertical: true, **attributes) ⇒ Component

Returns a new instance of Component.



28
29
30
31
32
# File 'app/components/shadcn/scroll_area/viewport/component.rb', line 28

def initialize(horizontal: false, vertical: true, **attributes)
  @horizontal = horizontal
  @vertical = vertical
  super(**attributes)
end

Instance Attribute Details

#horizontalObject (readonly)

Returns the value of attribute horizontal.



26
27
28
# File 'app/components/shadcn/scroll_area/viewport/component.rb', line 26

def horizontal
  @horizontal
end

#verticalObject (readonly)

Returns the value of attribute vertical.



26
27
28
# File 'app/components/shadcn/scroll_area/viewport/component.rb', line 26

def vertical
  @vertical
end

Instance Method Details

#callObject

display: table with min-width: 100%, which is Radix's own (:296-299) and is the only reason content size can be measured at all: a block child matches the viewport's width and would report the same number however wide its content really is.



58
59
60
61
62
63
64
65
66
# File 'app/components/shadcn/scroll_area/viewport/component.rb', line 58

def call
  render_element(
    body: tag.div(
      content,
      style: "min-width: 100%; display: table;",
      "data-shadcn--scroll-area-target": "content"
    )
  )
end

#element_attributes(**defaults) ⇒ Object

tabindex: 0, which Radix does not set — measured, there is no tabIndex anywhere in the primitive. A deliberate divergence, for three reasons that line up: axe fails a scrollable region with no keyboard access; Chrome and Firefox make scrollers focusable themselves and Safari does not, so without this the component's keyboard behaviour depends on the browser; and shadcn's own classes here style focus-visible, which only means anything on an element that can be focused. The sibling primitive shadcn publishes does set it on its viewport (vendor/shadcn-react/message-scroller/components.tsx:209).



43
44
45
46
47
48
49
50
51
52
# File 'app/components/shadcn/scroll_area/viewport/component.rb', line 43

def element_attributes(**defaults)
  super(**{
    tabindex: 0,
    style: merged_style(
      "overflow-x: #{horizontal ? 'scroll' : 'hidden'}; " \
      "overflow-y: #{vertical ? 'scroll' : 'hidden'};"
    ),
    "data-shadcn--scroll-area-target" => "viewport"
  }.merge(defaults))
end