primer_view_components 0.47.0 → 0.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -16
- data/app/assets/javascripts/components/primer/primer.d.ts +1 -0
- data/app/assets/javascripts/lib/primer/forms/character_counter.d.ts +41 -0
- data/app/assets/javascripts/lib/primer/forms/primer_text_area.d.ts +13 -0
- data/app/assets/javascripts/lib/primer/forms/primer_text_field.d.ts +2 -0
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/assets/styles/primer_view_components.css +1 -1
- data/app/assets/styles/primer_view_components.css.map +1 -1
- data/app/components/primer/alpha/action_list.css +1 -1
- data/app/components/primer/alpha/action_list.css.map +1 -1
- data/app/components/primer/alpha/auto_complete/auto_complete.html.erb +8 -6
- data/app/components/primer/alpha/text_area.rb +1 -0
- data/app/components/primer/alpha/text_field.css +1 -1
- data/app/components/primer/alpha/text_field.css.map +1 -1
- data/app/components/primer/alpha/text_field.rb +1 -0
- data/app/components/primer/alpha/toggle_switch.html.erb +2 -2
- data/app/components/primer/alpha/tool_tip.js +12 -5
- data/app/components/primer/alpha/tool_tip.ts +14 -5
- data/app/components/primer/alpha/underline_nav.css +1 -1
- data/app/components/primer/alpha/underline_nav.css.map +1 -1
- data/app/components/primer/beta/auto_complete/item.html.erb +5 -4
- data/app/components/primer/beta/avatar.rb +10 -2
- data/app/components/primer/beta/avatar_stack.css +1 -1
- data/app/components/primer/beta/avatar_stack.css.json +5 -3
- data/app/components/primer/beta/avatar_stack.css.map +1 -1
- data/app/components/primer/beta/avatar_stack.pcss +12 -1
- data/app/components/primer/beta/avatar_stack.rb +6 -0
- data/app/components/primer/beta/button.css +1 -1
- data/app/components/primer/beta/button.css.map +1 -1
- data/app/components/primer/beta/spinner.html.erb +2 -2
- data/app/components/primer/primer.d.ts +1 -0
- data/app/components/primer/primer.js +1 -0
- data/app/components/primer/primer.ts +1 -0
- data/app/forms/text_area_with_character_limit_form.rb +13 -0
- data/app/forms/text_field_with_character_limit_form.rb +13 -0
- data/app/lib/primer/forms/caption.html.erb +16 -9
- data/app/lib/primer/forms/character_counter.d.ts +41 -0
- data/app/lib/primer/forms/character_counter.js +114 -0
- data/app/lib/primer/forms/character_counter.ts +129 -0
- data/app/lib/primer/forms/dsl/input.rb +23 -0
- data/app/lib/primer/forms/dsl/text_area_input.rb +12 -1
- data/app/lib/primer/forms/dsl/text_field_input.rb +10 -1
- data/app/lib/primer/forms/primer_text_area.d.ts +13 -0
- data/app/lib/primer/forms/primer_text_area.js +53 -0
- data/app/lib/primer/forms/primer_text_area.ts +37 -0
- data/app/lib/primer/forms/primer_text_field.d.ts +2 -0
- data/app/lib/primer/forms/primer_text_field.js +16 -2
- data/app/lib/primer/forms/primer_text_field.ts +16 -3
- data/app/lib/primer/forms/text_area.html.erb +6 -4
- data/app/lib/primer/forms/text_field.rb +8 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/previews/primer/alpha/action_menu_preview/submitting_forms.html.erb +1 -1
- data/previews/primer/alpha/text_area_preview.rb +23 -2
- data/previews/primer/alpha/text_field_preview.rb +28 -7
- data/previews/primer/alpha/tree_view_preview/loading_failure.html.erb +53 -1
- data/previews/primer/beta/avatar_stack_preview.rb +9 -0
- data/previews/primer/forms_preview/text_area_with_character_limit_form.html.erb +3 -0
- data/previews/primer/forms_preview/text_field_with_character_limit_form.html.erb +3 -0
- data/previews/primer/forms_preview.rb +6 -0
- data/static/arguments.json +18 -0
- data/static/form_previews.json +10 -0
- data/static/info_arch.json +109 -0
- data/static/previews.json +91 -0
- metadata +14 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
.UnderlineNav{box-shadow:inset 0 -1px 0 var(--borderColor-muted);display:flex;min-height:var(--base-size-48);overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:auto;justify-content:space-between}.UnderlineNav .Counter{background-color:var(--bgColor-neutral-muted,var(--color-neutral-muted));color:var(--fgColor-default);margin-left:var(--control-medium-gap)}.UnderlineNav .Counter--primary{background-color:var(--bgColor-neutral-emphasis);color:var(--fgColor-onEmphasis)}.UnderlineNav-body{align-items:center;display:flex;gap:var(--control-medium-gap);list-style:none}.UnderlineNav-item{align-items:center;background-color:initial;border:0;border-radius:var(--borderRadius-medium);color:var(--fgColor-default);cursor:pointer;display:flex;font-size:var(--text-body-size-medium);line-height:30px;padding:0 var(--control-medium-paddingInline-condensed);position:relative;text-align:center;white-space:nowrap}.UnderlineNav-item:focus,.UnderlineNav-item:focus-visible,.UnderlineNav-item:hover{border-bottom-color:var(--borderColor-neutral-muted);color:var(--fgColor-default);outline-offset:-2px;-webkit-text-decoration:none;text-decoration:none;transition:border-bottom-color .12s ease-out}.UnderlineNav-item [data-content]:before{content:attr(data-content);display:block;font-weight:var(--base-text-weight-semibold);height:0;visibility:hidden}:is(.UnderlineNav-item:before){content:"";height:100%;left:50%;min-height:48px;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}@media (pointer:fine){.UnderlineNav-item:hover{background:var(--control-transparent-bgColor-hover);color:var(--fgColor-default);-webkit-text-decoration:none;text-decoration:none;transition:background .12s ease-out}}.UnderlineNav-item.selected,.UnderlineNav-item[aria-current]:not([aria-current=false]),.UnderlineNav-item[role=tab][aria-selected=true]{border-bottom-color:var(--underlineNav-borderColor-active);color:var(--fgColor-default);font-weight:var(--base-text-weight-semibold)}:is(.UnderlineNav-item.selected,.UnderlineNav-item[role=tab][aria-selected=true],.UnderlineNav-item[aria-current]:not([aria-current=false])):after{background:var(--underlineNav-borderColor-active);border-radius:var(--borderRadius-medium);bottom:calc(50% - var(--base-size-24));content:"";height:2px;position:absolute;right:50%;transform:translate(50%,-50%);width:100%;z-index:1}.UnderlineNav--right{justify-content:flex-end}.UnderlineNav--right .UnderlineNav-actions{flex:1 1 auto}.UnderlineNav-actions{align-self:center}.UnderlineNav--full{display:block}.UnderlineNav--full .UnderlineNav-body{min-height:var(--base-size-48)}.UnderlineNav-octicon{color:var(--fgColor-muted);display:inline!important;margin-right:var(--control-medium-gap)
|
|
1
|
+
.UnderlineNav{box-shadow:inset 0 -1px 0 var(--borderColor-muted);display:flex;min-height:var(--base-size-48);overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:auto;justify-content:space-between}.UnderlineNav .Counter{background-color:var(--bgColor-neutral-muted,var(--color-neutral-muted));color:var(--fgColor-default);margin-left:var(--control-medium-gap)}.UnderlineNav .Counter--primary{background-color:var(--bgColor-neutral-emphasis);color:var(--fgColor-onEmphasis)}.UnderlineNav-body{align-items:center;display:flex;gap:var(--control-medium-gap);list-style:none}.UnderlineNav-item{align-items:center;background-color:initial;border:0;border-radius:var(--borderRadius-medium);color:var(--fgColor-default);cursor:pointer;display:flex;font-size:var(--text-body-size-medium);line-height:30px;padding:0 var(--control-medium-paddingInline-condensed);position:relative;text-align:center;white-space:nowrap}.UnderlineNav-item:focus,.UnderlineNav-item:focus-visible,.UnderlineNav-item:hover{border-bottom-color:var(--borderColor-neutral-muted);color:var(--fgColor-default);outline-offset:-2px;-webkit-text-decoration:none;text-decoration:none;transition:border-bottom-color .12s ease-out}.UnderlineNav-item [data-content]:before{content:attr(data-content);display:block;font-weight:var(--base-text-weight-semibold);height:0;visibility:hidden}:is(.UnderlineNav-item:before){content:"";height:100%;left:50%;min-height:48px;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}@media (pointer:fine){.UnderlineNav-item:hover{background:var(--control-transparent-bgColor-hover);color:var(--fgColor-default);-webkit-text-decoration:none;text-decoration:none;transition:background .12s ease-out}}.UnderlineNav-item.selected,.UnderlineNav-item[aria-current]:not([aria-current=false]),.UnderlineNav-item[role=tab][aria-selected=true]{border-bottom-color:var(--underlineNav-borderColor-active);color:var(--fgColor-default);font-weight:var(--base-text-weight-semibold)}:is(.UnderlineNav-item.selected,.UnderlineNav-item[role=tab][aria-selected=true],.UnderlineNav-item[aria-current]:not([aria-current=false])):after{background:var(--underlineNav-borderColor-active);border-radius:var(--borderRadius-medium);bottom:calc(50% - var(--base-size-24));content:"";height:2px;position:absolute;right:50%;transform:translate(50%,-50%);width:100%;z-index:1}.UnderlineNav--right{justify-content:flex-end}.UnderlineNav--right .UnderlineNav-actions{flex:1 1 auto}.UnderlineNav-actions{align-self:center}.UnderlineNav--full{display:block}.UnderlineNav--full .UnderlineNav-body{min-height:var(--base-size-48)}.UnderlineNav-octicon{color:var(--fgColor-muted);display:inline!important;fill:var(--fgColor-muted);margin-right:var(--control-medium-gap)}.UnderlineNav-container{display:flex;justify-content:space-between}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["underline_nav.pcss","<no source>"],"names":[],"mappings":"AAEA,cAME,kDAAmD,CALnD,YAAa,CACb,8BAA+B,CAC/B,eAAgB,CAChB,iBAAkB,CAGlB,+BAAgC,CAChC,6BAaF,CAXE,uBAIE,wEAA0E,CAD1E,4BAA6B,CAD7B,qCAGF,CAEA,gCAEE,gDAAiD,CADjD,+BAEF,CAGF,mBAEE,kBAAmB,CADnB,YAAa,CAEb,6BAA8B,CAC9B,eACF,CAEA,mBAeE,kBAAmB,CAHnB,wBAA6B,CAC7B,QAAS,CACT,wCAAyC,CANzC,4BAA6B,CAG7B,cAAe,CATf,YAAa,CAGb,sCAAuC,CAEvC,gBAAiB,CAHjB,uDAAwD,CAHxD,iBAAkB,CAQlB,iBAAkB,CAClB,kBA+DF,CAxDE,mFAKE,oDAAqD,CAFrD,4BAA6B,CAG7B,mBAAoB,CAFpB,4BAAqB,CAArB,oBAAqB,CAGrB,4CACF,CAGA,yCAKE,0BAA2B,CAJ3B,aAAc,CAEd,4CAA6C,CAD7C,QAAS,CAET,iBAEF,CAIE,+BCtEJ,WAAA,YAAA,SAAA,gBAAA,kBAAA,QAAA,4CAAA,UDsE8B,CAI5B,sBACE,yBAGE,mDAAoD,CAFpD,4BAA6B,CAC7B,4BAAqB,CAArB,oBAAqB,CAErB,mCACF,CACF,CAEA,wIAKE,0DAA2D,CAD3D,4BAA6B,CAD7B,4CAkBF,CAbE,mJASE,iDAAkD,CAClD,wCAAyC,CAPzC,sCAAuC,CAIvC,UAAW,CADX,UAAW,CALX,iBAAkB,CAClB,SAAU,CASV,6BAA+B,CAN/B,UAAW,CADX,SAQF,CAIJ,qBACE,wBAKF,CAHE,2CACE,aACF,CAGF,sBACE,iBACF,CAEA,oBACE,aAMF,CAHE,uCACE,8BACF,CAGF,sBAIE,0BAA2B,CAH3B,wBAA0B,
|
|
1
|
+
{"version":3,"sources":["underline_nav.pcss","<no source>"],"names":[],"mappings":"AAEA,cAME,kDAAmD,CALnD,YAAa,CACb,8BAA+B,CAC/B,eAAgB,CAChB,iBAAkB,CAGlB,+BAAgC,CAChC,6BAaF,CAXE,uBAIE,wEAA0E,CAD1E,4BAA6B,CAD7B,qCAGF,CAEA,gCAEE,gDAAiD,CADjD,+BAEF,CAGF,mBAEE,kBAAmB,CADnB,YAAa,CAEb,6BAA8B,CAC9B,eACF,CAEA,mBAeE,kBAAmB,CAHnB,wBAA6B,CAC7B,QAAS,CACT,wCAAyC,CANzC,4BAA6B,CAG7B,cAAe,CATf,YAAa,CAGb,sCAAuC,CAEvC,gBAAiB,CAHjB,uDAAwD,CAHxD,iBAAkB,CAQlB,iBAAkB,CAClB,kBA+DF,CAxDE,mFAKE,oDAAqD,CAFrD,4BAA6B,CAG7B,mBAAoB,CAFpB,4BAAqB,CAArB,oBAAqB,CAGrB,4CACF,CAGA,yCAKE,0BAA2B,CAJ3B,aAAc,CAEd,4CAA6C,CAD7C,QAAS,CAET,iBAEF,CAIE,+BCtEJ,WAAA,YAAA,SAAA,gBAAA,kBAAA,QAAA,4CAAA,UDsE8B,CAI5B,sBACE,yBAGE,mDAAoD,CAFpD,4BAA6B,CAC7B,4BAAqB,CAArB,oBAAqB,CAErB,mCACF,CACF,CAEA,wIAKE,0DAA2D,CAD3D,4BAA6B,CAD7B,4CAkBF,CAbE,mJASE,iDAAkD,CAClD,wCAAyC,CAPzC,sCAAuC,CAIvC,UAAW,CADX,UAAW,CALX,iBAAkB,CAClB,SAAU,CASV,6BAA+B,CAN/B,UAAW,CADX,SAQF,CAIJ,qBACE,wBAKF,CAHE,2CACE,aACF,CAGF,sBACE,iBACF,CAEA,oBACE,aAMF,CAHE,uCACE,8BACF,CAGF,sBAIE,0BAA2B,CAH3B,wBAA0B,CAI1B,yBAA0B,CAF1B,sCAGF,CAEA,wBACE,YAAa,CACb,6BACF","file":"underline_nav.css","sourcesContent":["/* UnderlineNav */\n\n.UnderlineNav {\n display: flex;\n min-height: var(--base-size-48);\n overflow-x: auto;\n overflow-y: hidden;\n /* stylelint-disable-next-line primer/box-shadow */\n box-shadow: inset 0 -1px 0 var(--borderColor-muted);\n -webkit-overflow-scrolling: auto;\n justify-content: space-between;\n\n & .Counter {\n /* stylelint-disable-next-line primer/spacing */\n margin-left: var(--control-medium-gap);\n color: var(--fgColor-default);\n background-color: var(--bgColor-neutral-muted, var(--color-neutral-muted));\n }\n\n & .Counter--primary {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-neutral-emphasis);\n }\n}\n\n.UnderlineNav-body {\n display: flex;\n align-items: center;\n gap: var(--control-medium-gap);\n list-style: none;\n}\n\n.UnderlineNav-item {\n position: relative;\n display: flex;\n /* stylelint-disable-next-line primer/spacing */\n padding: 0 var(--control-medium-paddingInline-condensed);\n font-size: var(--text-body-size-medium);\n /* stylelint-disable-next-line primer/typography */\n line-height: 30px;\n color: var(--fgColor-default);\n text-align: center;\n white-space: nowrap;\n cursor: pointer;\n background-color: transparent;\n border: 0;\n border-radius: var(--borderRadius-medium);\n align-items: center;\n\n &:hover,\n &:focus,\n &:focus-visible {\n color: var(--fgColor-default);\n text-decoration: none;\n border-bottom-color: var(--borderColor-neutral-muted);\n outline-offset: -2px;\n transition: border-bottom-color 0.12s ease-out;\n }\n\n /* renders a visibly hidden \"copy\" of the label in bold, reserving box space for when label becomes bold on selected */\n & [data-content]::before {\n display: block;\n height: 0;\n font-weight: var(--base-text-weight-semibold);\n visibility: hidden;\n content: attr(data-content);\n }\n\n /* increase touch target area */\n &::before {\n @mixin minTouchTarget 48px;\n }\n\n /* hover state was \"sticking\" on mobile after click */\n @media (pointer: fine) {\n &:hover {\n color: var(--fgColor-default);\n text-decoration: none;\n background: var(--control-transparent-bgColor-hover);\n transition: background 0.12s ease-out;\n }\n }\n\n &.selected,\n &[role='tab'][aria-selected='true'],\n &[aria-current]:not([aria-current='false']) {\n font-weight: var(--base-text-weight-semibold);\n color: var(--fgColor-default);\n border-bottom-color: var(--underlineNav-borderColor-active);\n\n /* current/selected underline */\n &::after {\n position: absolute;\n right: 50%;\n bottom: calc(50% - var(--base-size-24)); /* 48px total height / 2 (24px) + 1px */\n z-index: 1; /* raise above full-width flash banner */\n width: 100%;\n height: 2px;\n content: '';\n /* stylelint-disable-next-line primer/colors */\n background: var(--underlineNav-borderColor-active);\n border-radius: var(--borderRadius-medium);\n transform: translate(50%, -50%);\n }\n }\n}\n\n.UnderlineNav--right {\n justify-content: flex-end;\n\n & .UnderlineNav-actions {\n flex: 1 1 auto;\n }\n}\n\n.UnderlineNav-actions {\n align-self: center;\n}\n\n.UnderlineNav--full {\n display: block;\n\n /* required for underline to align with additional wrapper element */\n & .UnderlineNav-body {\n min-height: var(--base-size-48);\n }\n}\n\n.UnderlineNav-octicon {\n display: inline !important;\n /* stylelint-disable-next-line primer/spacing */\n margin-right: var(--control-medium-gap);\n color: var(--fgColor-muted);\n fill: var(--fgColor-muted);\n}\n\n.UnderlineNav-container {\n display: flex;\n justify-content: space-between;\n}\n",null]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
|
2
2
|
<span class="ActionListContent">
|
|
3
3
|
<% if leading_visual %>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
<span class="ActionListItem-visual ActionListItem-visual--leading">
|
|
5
|
+
<%= leading_visual %>
|
|
6
|
+
</span>
|
|
7
7
|
<% end %>
|
|
8
8
|
<%= render(Primer::ConditionalWrapper.new(condition: description?, tag: :span, **@description_wrapper_arguments)) do %>
|
|
9
9
|
<span class="ActionListItem-label"><%= content %></span>
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
</span>
|
|
14
14
|
<% end %>
|
|
15
15
|
<% end %>
|
|
16
|
-
|
|
16
|
+
<% if trailing_visual %>
|
|
17
17
|
<span class="ActionListItem-visual ActionListItem-visual--trailing">
|
|
18
18
|
<%= trailing_visual %>
|
|
19
19
|
</span>
|
|
20
20
|
<% end %>
|
|
21
|
+
</span>
|
|
21
22
|
<% end %>
|
|
@@ -19,6 +19,10 @@ module Primer
|
|
|
19
19
|
class Avatar < Primer::Component
|
|
20
20
|
status :beta
|
|
21
21
|
|
|
22
|
+
def link?
|
|
23
|
+
@href.present?
|
|
24
|
+
end
|
|
25
|
+
|
|
22
26
|
DEFAULT_SIZE = 20
|
|
23
27
|
SMALL_THRESHOLD = 24
|
|
24
28
|
|
|
@@ -32,9 +36,11 @@ module Primer
|
|
|
32
36
|
# @param size [Integer] <%= one_of(Primer::Beta::Avatar::SIZE_OPTIONS) %>
|
|
33
37
|
# @param shape [Symbol] Shape of the avatar. <%= one_of(Primer::Beta::Avatar::SHAPE_OPTIONS) %>
|
|
34
38
|
# @param href [String] The URL to link to. If used, component will be wrapped by an `<a>` tag.
|
|
39
|
+
# @param tooltip [String] Tooltip text to display on hover when href is provided.
|
|
35
40
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
|
36
|
-
def initialize(src:, alt: nil, size: DEFAULT_SIZE, shape: DEFAULT_SHAPE, href: nil, **system_arguments)
|
|
41
|
+
def initialize(src:, alt: nil, size: DEFAULT_SIZE, shape: DEFAULT_SHAPE, href: nil, tooltip: nil, **system_arguments)
|
|
37
42
|
@href = href
|
|
43
|
+
@tooltip = tooltip
|
|
38
44
|
@system_arguments = deny_tag_argument(**system_arguments)
|
|
39
45
|
@system_arguments[:tag] = :img
|
|
40
46
|
@system_arguments[:src] = src
|
|
@@ -54,7 +60,9 @@ module Primer
|
|
|
54
60
|
|
|
55
61
|
def call
|
|
56
62
|
if @href
|
|
57
|
-
|
|
63
|
+
link_id = @tooltip.present? ? self.class.generate_id : nil
|
|
64
|
+
render(Primer::Beta::Link.new(href: @href, classes: @system_arguments[:classes], id: link_id)) do |link|
|
|
65
|
+
link.with_tooltip(text: @tooltip) if @tooltip.present?
|
|
58
66
|
render(Primer::BaseComponent.new(**@system_arguments.except(:classes))) { content }
|
|
59
67
|
end
|
|
60
68
|
else
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.AvatarStack{height:20px;min-width:26px;position:relative}.AvatarStack .AvatarStack-body{position:absolute}.AvatarStack.AvatarStack--two{min-width:36px}.AvatarStack.AvatarStack--three-plus{min-width:46px}.AvatarStack-body{background:var(--bgColor-default);border-radius:100px;display:flex}.AvatarStack-body .avatar{background-color:var(--bgColor-default);border-radius:var(--borderRadius-small);box-sizing:initial;display:flex;height:20px;margin-right:-11px;position:relative;transition:margin .1s ease-in-out;width:20px;z-index:2}:is(.AvatarStack-body .avatar):first-child{z-index:3}:is(.AvatarStack-body .avatar):last-child{z-index:1}:is(.AvatarStack-body .avatar) img{border-radius:var(--borderRadius-small)}:is(.AvatarStack-body .avatar):nth-child(n+4){display:none;opacity:0}.AvatarStack-body:hover:not([data-disable-expand]) .avatar{margin-right:var(--base-size-4)}.AvatarStack-body:hover:not([data-disable-expand]) .avatar:nth-child(n+4){display:flex;opacity:1}.AvatarStack-body:hover:not([data-disable-expand]) .avatar-more{display:none!important}.AvatarStack-body[data-disable-expand]{position:relative}.avatar.avatar-more{background:var(--bgColor-muted);margin-right:0;z-index:1}.avatar.avatar-more:after,.avatar.avatar-more:before{border-radius:2px;content:"";display:block;height:20px;outline:var(--borderWidth-thin) solid var(--bgColor-default);position:absolute}.avatar.avatar-more:before{background:var(--avatarStack-fade-bgColor-muted);width:17px}.avatar.avatar-more:after{background:var(--avatarStack-fade-bgColor-default);width:14px}.AvatarStack--right .AvatarStack-body{flex-direction:row-reverse;right:0}:is(.AvatarStack--right .AvatarStack-body):hover:not([data-disable-expand]) .avatar{margin-left:var(--base-size-4);margin-right:0}.AvatarStack--right .avatar.avatar-more{background:var(--avatarStack-fade-bgColor-default)}:is(.AvatarStack--right .avatar.avatar-more):before{width:5px}:is(.AvatarStack--right .avatar.avatar-more):after{background:var(--bgColor-muted);width:2px}.AvatarStack--right .avatar{margin-left:-11px;margin-right:0}
|
|
1
|
+
.AvatarStack{height:20px;min-width:26px;position:relative}.AvatarStack .AvatarStack-body{position:absolute}.AvatarStack.AvatarStack--two{min-width:36px}.AvatarStack.AvatarStack--three-plus{min-width:46px}.AvatarStack-body{background:var(--bgColor-default);border-radius:100px;display:flex}.AvatarStack-body .avatar{background-color:var(--bgColor-default);border-radius:var(--borderRadius-small);box-sizing:initial;display:flex;height:20px;margin-right:-11px;position:relative;transition:margin .1s ease-in-out;width:20px;z-index:2}:is(.AvatarStack-body .avatar):first-child{z-index:3}:is(.AvatarStack-body .avatar):last-child{z-index:1}:is(.AvatarStack-body .avatar) img{border-radius:var(--borderRadius-small)}.AvatarStack-body span:nth-child(n+4) .avatar,:is(.AvatarStack-body .avatar):nth-child(n+4){display:none;opacity:0}:is(.AvatarStack-body:hover:not([data-disable-expand]),.AvatarStack-body:focus-within:not([data-disable-expand])) .avatar{margin-right:var(--base-size-4)}:is(.AvatarStack-body:hover:not([data-disable-expand]),.AvatarStack-body:focus-within:not([data-disable-expand])) .avatar:nth-child(n+4),:is(.AvatarStack-body:hover:not([data-disable-expand]),.AvatarStack-body:focus-within:not([data-disable-expand])) span:nth-child(n+4) .avatar{display:flex;opacity:1}:is(.AvatarStack-body:hover:not([data-disable-expand]),.AvatarStack-body:focus-within:not([data-disable-expand])) .avatar-more{display:none!important}.AvatarStack-body[data-disable-expand]{position:relative}.avatar.avatar-more{background:var(--bgColor-muted);margin-right:0;z-index:1}.avatar.avatar-more:after,.avatar.avatar-more:before{border-radius:2px;content:"";display:block;height:20px;outline:var(--borderWidth-thin) solid var(--bgColor-default);position:absolute}.avatar.avatar-more:before{background:var(--avatarStack-fade-bgColor-muted);width:17px}.avatar.avatar-more:after{background:var(--avatarStack-fade-bgColor-default);width:14px}.AvatarStack--right .AvatarStack-body{flex-direction:row-reverse;right:0}:is(.AvatarStack--right .AvatarStack-body):hover:not([data-disable-expand]) .avatar{margin-left:var(--base-size-4);margin-right:0}.AvatarStack--right .avatar.avatar-more{background:var(--avatarStack-fade-bgColor-default)}:is(.AvatarStack--right .avatar.avatar-more):before{width:5px}:is(.AvatarStack--right .avatar.avatar-more):after{background:var(--bgColor-muted);width:2px}.AvatarStack--right .avatar{margin-left:-11px;margin-right:0}
|
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
":is(.AvatarStack-body .avatar):first-child",
|
|
11
11
|
":is(.AvatarStack-body .avatar):last-child",
|
|
12
12
|
":is(.AvatarStack-body .avatar) img",
|
|
13
|
+
".AvatarStack-body span:nth-child(n+4) .avatar",
|
|
13
14
|
":is(.AvatarStack-body .avatar):nth-child(n+4)",
|
|
14
|
-
".AvatarStack-body:hover:not([data-disable-expand]) .avatar",
|
|
15
|
-
".AvatarStack-body:hover:not([data-disable-expand]) .avatar:nth-child(n+4)",
|
|
16
|
-
".AvatarStack-body:hover:not([data-disable-expand]) .avatar
|
|
15
|
+
":is(.AvatarStack-body:hover:not([data-disable-expand]),.AvatarStack-body:focus-within:not([data-disable-expand])) .avatar",
|
|
16
|
+
":is(.AvatarStack-body:hover:not([data-disable-expand]),.AvatarStack-body:focus-within:not([data-disable-expand])) .avatar:nth-child(n+4)",
|
|
17
|
+
":is(.AvatarStack-body:hover:not([data-disable-expand]),.AvatarStack-body:focus-within:not([data-disable-expand])) span:nth-child(n+4) .avatar",
|
|
18
|
+
":is(.AvatarStack-body:hover:not([data-disable-expand]),.AvatarStack-body:focus-within:not([data-disable-expand])) .avatar-more",
|
|
17
19
|
".AvatarStack-body[data-disable-expand]",
|
|
18
20
|
".avatar.avatar-more",
|
|
19
21
|
".avatar.avatar-more:after",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["avatar_stack.pcss"],"names":[],"mappings":"AAUA,aAGE,WAAY,CADZ,cAAe,CADf,iBAeF,CAXE,+BACE,iBACF,CAEA,8BACE,cACF,CAEA,qCACE,cACF,CAGF,kBAEE,iCAAkC,CAElC,mBAAoB,CAHpB,
|
|
1
|
+
{"version":3,"sources":["avatar_stack.pcss"],"names":[],"mappings":"AAUA,aAGE,WAAY,CADZ,cAAe,CADf,iBAeF,CAXE,+BACE,iBACF,CAEA,8BACE,cACF,CAEA,qCACE,cACF,CAGF,kBAEE,iCAAkC,CAElC,mBAAoB,CAHpB,YAmEF,CA9DE,0BASE,uCAAwC,CACxC,uCAAwC,CAJxC,kBAAuB,CAHvB,YAAa,CAEb,WAAY,CAGZ,kBAAmB,CAPnB,iBAAkB,CAUlB,iCAAmC,CAPnC,UAAW,CAFX,SA6BF,CAlBE,2CACE,SACF,CAEA,0CACE,SACF,CAGA,mCACE,uCACF,CASF,4FACE,YAAa,CACb,SACF,CAIE,0HACE,+BACF,CAOA,uRACE,YAAa,CACb,SACF,CAEA,+HACE,sBACF,CAGF,uCACE,iBACF,CAGF,oBAGE,+BAAgC,CADhC,cAAe,CADf,SAwBF,CApBE,qDAOE,iBAAkB,CAFlB,UAAW,CAFX,aAAc,CACd,WAAY,CAIZ,4DAA6D,CAN7D,iBAOF,CAEA,2BAEE,gDAAiD,CADjD,UAEF,CAEA,0BAEE,kDAAmD,CADnD,UAEF,CAMA,sCAEE,0BAA2B,CAD3B,OAOF,CAJE,oFAEE,8BAA+B,CAD/B,cAEF,CAGF,wCACE,kDAUF,CARE,oDACE,SACF,CAEA,mDAEE,+BAAgC,CADhC,SAEF,CAGF,4BAGE,iBAAkB,CAFlB,cAGF","file":"avatar_stack.css","sourcesContent":["/* stylelint-disable selector-max-specificity */\n/* The selector-max-specificity rule is disabled here because the nested selectors\n in AvatarStack require high specificity to properly override default styles and \n achieve the intended visual stacking. */\n\n/* AvatarStack */\n\n/* Stacked avatars can be used to show who is participating in thread when\n** there is limited space available. */\n\n.AvatarStack {\n position: relative;\n min-width: 26px;\n height: 20px;\n\n & .AvatarStack-body {\n position: absolute;\n }\n\n &.AvatarStack--two {\n min-width: 36px;\n }\n\n &.AvatarStack--three-plus {\n min-width: 46px;\n }\n}\n\n.AvatarStack-body {\n display: flex;\n background: var(--bgColor-default);\n /* stylelint-disable-next-line primer/borders */\n border-radius: 100px;\n\n & .avatar {\n position: relative;\n z-index: 2;\n display: flex;\n width: 20px;\n height: 20px;\n box-sizing: content-box;\n /* stylelint-disable-next-line primer/spacing */\n margin-right: -11px;\n background-color: var(--bgColor-default);\n border-radius: var(--borderRadius-small);\n transition: margin 0.1s ease-in-out;\n\n &:first-child {\n z-index: 3;\n }\n\n &:last-child {\n z-index: 1;\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & img {\n border-radius: var(--borderRadius-small);\n }\n\n /* Account for 4+ avatars */\n &:nth-child(n + 4) {\n display: none;\n opacity: 0;\n }\n }\n /* stylelint-disable-next-line selector-max-type */\n & span:nth-child(n + 4) .avatar {\n display: none;\n opacity: 0;\n }\n\n &:hover:not([data-disable-expand]),\n &:focus-within:not([data-disable-expand]) {\n & .avatar {\n margin-right: var(--base-size-4);\n }\n\n & .avatar:nth-child(n + 4) {\n display: flex;\n opacity: 1;\n }\n /* stylelint-disable-next-line selector-max-type */\n & span:nth-child(n + 4) .avatar {\n display: flex;\n opacity: 1;\n }\n\n & .avatar-more {\n display: none !important;\n }\n }\n\n &[data-disable-expand] {\n position: relative;\n }\n}\n\n.avatar.avatar-more {\n z-index: 1;\n margin-right: 0;\n background: var(--bgColor-muted);\n\n &::before,\n &::after {\n position: absolute;\n display: block;\n height: 20px;\n content: '';\n /* stylelint-disable-next-line primer/borders */\n border-radius: 2px;\n outline: var(--borderWidth-thin) solid var(--bgColor-default);\n }\n\n &::before {\n width: 17px;\n background: var(--avatarStack-fade-bgColor-muted);\n }\n\n &::after {\n width: 14px;\n background: var(--avatarStack-fade-bgColor-default);\n }\n}\n\n/* Right aligned variation */\n\n.AvatarStack--right {\n & .AvatarStack-body {\n right: 0;\n flex-direction: row-reverse;\n\n &:hover:not([data-disable-expand]) .avatar {\n margin-right: 0;\n margin-left: var(--base-size-4);\n }\n }\n\n & .avatar.avatar-more {\n background: var(--avatarStack-fade-bgColor-default);\n\n &::before {\n width: 5px;\n }\n\n &::after {\n width: 2px;\n background: var(--bgColor-muted);\n }\n }\n\n & .avatar {\n margin-right: 0;\n /* stylelint-disable-next-line primer/spacing */\n margin-left: -11px;\n }\n}\n"]}
|
|
@@ -64,8 +64,14 @@
|
|
|
64
64
|
opacity: 0;
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
+
/* stylelint-disable-next-line selector-max-type */
|
|
68
|
+
& span:nth-child(n + 4) .avatar {
|
|
69
|
+
display: none;
|
|
70
|
+
opacity: 0;
|
|
71
|
+
}
|
|
67
72
|
|
|
68
|
-
&:hover:not([data-disable-expand])
|
|
73
|
+
&:hover:not([data-disable-expand]),
|
|
74
|
+
&:focus-within:not([data-disable-expand]) {
|
|
69
75
|
& .avatar {
|
|
70
76
|
margin-right: var(--base-size-4);
|
|
71
77
|
}
|
|
@@ -74,6 +80,11 @@
|
|
|
74
80
|
display: flex;
|
|
75
81
|
opacity: 1;
|
|
76
82
|
}
|
|
83
|
+
/* stylelint-disable-next-line selector-max-type */
|
|
84
|
+
& span:nth-child(n + 4) .avatar {
|
|
85
|
+
display: flex;
|
|
86
|
+
opacity: 1;
|
|
87
|
+
}
|
|
77
88
|
|
|
78
89
|
& .avatar-more {
|
|
79
90
|
display: none !important;
|
|
@@ -79,6 +79,12 @@ module Primer
|
|
|
79
79
|
"AvatarStack--two" => avatars.size == 2,
|
|
80
80
|
"AvatarStack--three-plus" => avatars.size > 2
|
|
81
81
|
)
|
|
82
|
+
|
|
83
|
+
# Make non-linked stacks keyboard-focusable so :focus-within triggers expansion (avoid extra focus stop when avatars are links).
|
|
84
|
+
unless @tooltipped || @disable_expand
|
|
85
|
+
has_linked_avatars = avatars.any?(&:link?)
|
|
86
|
+
@body_arguments[:tabindex] ||= 0 unless has_linked_avatars
|
|
87
|
+
end
|
|
82
88
|
end
|
|
83
89
|
|
|
84
90
|
def render?
|
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--duration-fast:80ms;--easing-easeInOut:cubic-bezier(0.65,0,0.35,1)}.Button{align-items:center;background-color:initial;border:var(--borderWidth-thin) solid;border-color:#0000;border-radius:var(--borderRadius-medium);color:var(--button-default-fgColor-rest);cursor:pointer;display:inline-flex;flex-direction:row;font-size:var(--text-body-size-medium);font-weight:var(--base-text-weight-medium);gap:var(--base-size-4);height:var(--control-medium-size);justify-content:space-between;min-width:max-content;padding:0 var(--control-medium-paddingInline-normal);position:relative;text-align:center;transition:var(--duration-fast) var(--easing-easeInOut);transition-property:color,fill,background-color,border-color;-webkit-user-select:none;user-select:none}@media (pointer:coarse){:is(.Button:before){content:"";height:100%;left:50%;min-height:48px;min-width:48px;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}}.Button:hover{transition-duration:var(--duration-fast)}.Button:active{transition:none}.Button:disabled,.Button[aria-disabled=true]{box-shadow:none;cursor:not-allowed}.Button.Button--iconOnly{color:var(--fgColor-muted)}:is(a.Button,summary.Button):hover{-webkit-text-decoration:none;text-decoration:none}.Button-content{align-items:center;display:grid;flex:1 0 auto;grid-template-areas:"leadingVisual text trailingVisual";grid-template-columns:min-content minmax(0,auto) min-content;place-content:center}.Button-content>:not(:last-child){margin-right:var(--control-medium-gap)}.Button-content--alignStart{justify-content:start}.Button-visual{display:flex;pointer-events:none}.Button-visual .Counter{background-color:var(--buttonCounter-default-bgColor-rest);color:inherit}.Button-label{grid-area:text;line-height:var(--text-body-lineHeight-medium);white-space:nowrap}.Button-leadingVisual{grid-area:leadingVisual}.Button-leadingVisual svg{fill:currentcolor}.Button-trailingVisual{grid-area:trailingVisual}.Button-trailingAction{margin-right:calc(var(--base-size-4)*-1)}.Button--small{font-size:var(--text-body-size-small);gap:var(--control-small-gap);height:var(--control-small-size);min-width:var(--control-small-size);padding:0 var(--control-small-paddingInline-condensed)}.Button--small .Button-label{line-height:var(--text-body-lineHeight-small)}:is(.Button--small .Button-content)>:not(:last-child){margin-right:var(--control-small-gap)}.Button--large{gap:var(--control-large-gap);height:var(--control-large-size);padding:0 var(--control-large-paddingInline-spacious)}.Button--large .Button-label{line-height:var(--text-body-lineHeight-large)}:is(.Button--large .Button-content)>:not(:last-child){margin-right:var(--control-large-gap)}.Button--fullWidth{width:100%}.Button--labelWrap{height:unset;min-height:var(--control-medium-size);min-width:fit-content}.Button--labelWrap .Button-content{align-self:stretch;flex:1 1 auto;padding-block:calc(var(--control-medium-paddingBlock) - var(--base-size-2))}.Button--labelWrap .Button-label{white-space:unset}.Button--labelWrap.Button--small{height:unset;min-height:var(--control-small-size)}.Button--labelWrap.Button--small .Button-content{padding-block:calc(var(--control-small-paddingBlock) - var(--base-size-2))}.Button--labelWrap.Button--large{height:unset;min-height:var(--control-large-size);padding-inline:var(--control-large-paddingInline-spacious)}.Button--labelWrap.Button--large .Button-content{padding-block:calc(var(--control-large-paddingBlock) - var(--base-size-2))}.Button--primary{
|
|
1
|
+
:root{--duration-fast:80ms;--easing-easeInOut:cubic-bezier(0.65,0,0.35,1)}.Button{align-items:center;background-color:initial;border:var(--borderWidth-thin) solid;border-color:#0000;border-radius:var(--borderRadius-medium);color:var(--button-default-fgColor-rest);cursor:pointer;display:inline-flex;flex-direction:row;font-size:var(--text-body-size-medium);font-weight:var(--base-text-weight-medium);gap:var(--base-size-4);height:var(--control-medium-size);justify-content:space-between;min-width:max-content;padding:0 var(--control-medium-paddingInline-normal);position:relative;text-align:center;transition:var(--duration-fast) var(--easing-easeInOut);transition-property:color,fill,background-color,border-color;-webkit-user-select:none;user-select:none}@media (pointer:coarse){:is(.Button:before){content:"";height:100%;left:50%;min-height:48px;min-width:48px;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}}.Button:hover{transition-duration:var(--duration-fast)}.Button:active{transition:none}.Button:disabled,.Button[aria-disabled=true]{box-shadow:none;cursor:not-allowed}.Button.Button--iconOnly{color:var(--fgColor-muted)}:is(a.Button,summary.Button):hover{-webkit-text-decoration:none;text-decoration:none}.Button-content{align-items:center;display:grid;flex:1 0 auto;grid-template-areas:"leadingVisual text trailingVisual";grid-template-columns:min-content minmax(0,auto) min-content;place-content:center}.Button-content>:not(:last-child){margin-right:var(--control-medium-gap)}.Button-content--alignStart{justify-content:start}.Button-visual{display:flex;pointer-events:none}.Button-visual .Counter{background-color:var(--buttonCounter-default-bgColor-rest);color:inherit}.Button-label{grid-area:text;line-height:var(--text-body-lineHeight-medium);white-space:nowrap}.Button-leadingVisual{grid-area:leadingVisual}.Button-leadingVisual svg{fill:currentcolor}.Button-trailingVisual{grid-area:trailingVisual}.Button-trailingAction{margin-right:calc(var(--base-size-4)*-1)}.Button--small{font-size:var(--text-body-size-small);gap:var(--control-small-gap);height:var(--control-small-size);min-width:var(--control-small-size);padding:0 var(--control-small-paddingInline-condensed)}.Button--small .Button-label{line-height:var(--text-body-lineHeight-small)}:is(.Button--small .Button-content)>:not(:last-child){margin-right:var(--control-small-gap)}.Button--large{gap:var(--control-large-gap);height:var(--control-large-size);padding:0 var(--control-large-paddingInline-spacious)}.Button--large .Button-label{line-height:var(--text-body-lineHeight-large)}:is(.Button--large .Button-content)>:not(:last-child){margin-right:var(--control-large-gap)}.Button--fullWidth{width:100%}.Button--labelWrap{height:unset;min-height:var(--control-medium-size);min-width:fit-content}.Button--labelWrap .Button-content{align-self:stretch;flex:1 1 auto;padding-block:calc(var(--control-medium-paddingBlock) - var(--base-size-2))}.Button--labelWrap .Button-label{white-space:unset}.Button--labelWrap.Button--small{height:unset;min-height:var(--control-small-size)}.Button--labelWrap.Button--small .Button-content{padding-block:calc(var(--control-small-paddingBlock) - var(--base-size-2))}.Button--labelWrap.Button--large{height:unset;min-height:var(--control-large-size);padding-inline:var(--control-large-paddingInline-spacious)}.Button--labelWrap.Button--large .Button-content{padding-block:calc(var(--control-large-paddingBlock) - var(--base-size-2))}.Button--primary{background-color:var(--button-primary-bgColor-rest);border-color:var(--button-primary-borderColor-rest);box-shadow:var(--shadow-resting-small,var(--color-btn-primary-shadow));color:var(--button-primary-fgColor-rest);fill:var(--button-primary-iconColor-rest)}.Button--primary.Button--iconOnly{color:var(--button-primary-iconColor-rest)}.Button--primary:hover:not(:disabled,.Button--inactive){background-color:var(--button-primary-bgColor-hover);border-color:var(--button-primary-borderColor-hover)}.Button--primary:focus{box-shadow:inset 0 0 0 3px var(--fgColor-onEmphasis);outline:2px solid var(--focus-outlineColor);outline-offset:-2px}.Button--primary:focus:not(:focus-visible){box-shadow:none;outline:1px solid #0000}.Button--primary:focus-visible{box-shadow:inset 0 0 0 3px var(--fgColor-onEmphasis);outline:2px solid var(--focus-outlineColor);outline-offset:-2px}.Button--primary:active:not(:disabled),.Button--primary[aria-pressed=true]{background-color:var(--button-primary-bgColor-active);box-shadow:var(--button-primary-shadow-selected)}.Button--primary:disabled,.Button--primary[aria-disabled=true]{background-color:var(--button-primary-bgColor-disabled);border-color:var(--button-primary-borderColor-disabled);color:var(--button-primary-fgColor-disabled);fill:var(--button-primary-fgColor-disabled)}.Button--primary .Counter{background-color:var(--buttonCounter-primary-bgColor-rest);color:inherit}.Button--secondary{background-color:var(--button-default-bgColor-rest);border-color:var(--button-default-borderColor-rest);box-shadow:var(--button-default-shadow-resting),var(--button-default-shadow-inset);color:var(--button-default-fgColor-rest);fill:var(--fgColor-muted)}.Button--secondary:hover:not(:disabled,.Button--inactive){background-color:var(--button-default-bgColor-hover);border-color:var(--button-default-borderColor-hover)}.Button--secondary:active:not(:disabled){background-color:var(--button-default-bgColor-active);border-color:var(--button-default-borderColor-active)}.Button--secondary[aria-pressed=true]{background-color:var(--button-default-bgColor-selected);box-shadow:var(--shadow-inset)}.Button--secondary:disabled,.Button--secondary[aria-disabled=true]{background-color:var(--button-default-bgColor-disabled);border-color:var(--button-default-borderColor-disabled);color:var(--control-fgColor-disabled);fill:var(--control-fgColor-disabled)}.Button--invisible{color:var(--button-invisible-fgColor-rest)}.Button--invisible.Button--iconOnly{color:var(--button-invisible-iconColor-rest,var(--color-fg-muted))}.Button--invisible:hover:not(:disabled,.Button--inactive){background-color:var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg))}.Button--invisible:active:not(:disabled),.Button--invisible[aria-pressed=true]{background-color:var(--button-invisible-bgColor-active)}.Button--invisible:disabled,.Button--invisible[aria-disabled=true]{background-color:var(--button-invisible-bgColor-disabled);border-color:var(--button-invisible-borderColor-disabled);color:var(--button-invisible-fgColor-disabled);fill:var(--button-invisible-fgColor-disabled)}.Button--invisible.Button--invisible-noVisuals .Button-label{color:var(--button-invisible-fgColor-rest)}.Button--invisible .Button-visual{color:var(--button-invisible-iconColor-rest,var(--color-fg-muted))}:is(.Button--invisible .Button-visual) .Counter{color:var(--fgColor-default)}.Button--link{border:none;color:var(--fgColor-link);display:inline-block;fill:var(--fgColor-link);font-size:inherit;height:unset;min-width:fit-content;padding:0}.Button--link:hover:not(:disabled,.Button--inactive){-webkit-text-decoration:underline;text-decoration:underline}.Button--link:focus,.Button--link:focus-visible{outline-offset:2px}.Button--link:disabled,.Button--link[aria-disabled=true]{background-color:initial;border-color:#0000;color:var(--control-fgColor-disabled);fill:var(--control-fgColor-disabled)}.Button--link .Button-label{white-space:unset}.Button--danger{background-color:var(--button-danger-bgColor-rest);border-color:var(--button-danger-borderColor-rest);box-shadow:var(--button-default-shadow-resting),var(--button-default-shadow-inset);color:var(--button-danger-fgColor-rest);fill:var(--button-danger-iconColor-rest)}.Button--danger.Button--iconOnly{color:var(--button-danger-iconColor-rest)}.Button--danger:hover:not(:disabled,.Button--inactive){background-color:var(--button-danger-bgColor-hover);border-color:var(--button-danger-borderColor-hover);box-shadow:var(--shadow-resting-small);color:var(--button-danger-fgColor-hover);fill:var(--button-danger-fgColor-hover)}.Button--danger:hover:not(:disabled,.Button--inactive) .Counter{background-color:var(--buttonCounter-danger-bgColor-hover);color:var(--buttonCounter-danger-fgColor-hover)}.Button--danger:active:not(:disabled),.Button--danger[aria-pressed=true]{background-color:var(--button-danger-bgColor-active);border-color:var(--button-danger-borderColor-active);box-shadow:var(--button-danger-shadow-selected);color:var(--button-danger-fgColor-active);fill:var(--button-danger-fgColor-active)}.Button--danger:disabled,.Button--danger[aria-disabled=true]{background-color:var(--button-danger-bgColor-disabled);border-color:var(--button-default-borderColor-disabled);color:var(--button-danger-fgColor-disabled);fill:var(--button-danger-fgColor-disabled)}:is(.Button--danger:disabled,.Button--danger[aria-disabled=true]) .Counter{background-color:var(--buttonCounter-danger-bgColor-disabled);color:var(--buttonCounter-danger-fgColor-disabled)}.Button--danger .Counter{background-color:var(--buttonCounter-danger-bgColor-rest);color:var(--buttonCounter-danger-fgColor-rest)}.Button--iconOnly{display:inline-grid;padding:unset;place-content:center;width:var(--control-medium-size)}.Button--iconOnly.Button--small{width:var(--control-small-size)}.Button--iconOnly.Button--large{width:var(--control-large-size)}.Button--inactive:not([aria-disabled=true],:disabled){background-color:var(--button-inactive-bgColor);border:0;color:var(--button-inactive-fgColor);cursor:default}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["button.pcss","<no source>","../../../../lib/postcss_mixins/focusOutlineOnEmphasis.pcss"],"names":[],"mappings":"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","file":"button.css","sourcesContent":["/* stylelint-disable selector-no-qualifying-type */\n/* stylelint-disable selector-max-type */\n/* stylelint-disable primer/spacing */\n\n/* CSS for Button */\n\n/* temporary, pre primitives release */\n:root {\n --duration-fast: 80ms;\n --easing-easeInOut: cubic-bezier(0.65, 0, 0.35, 1);\n}\n\n/* base button */\n.Button {\n position: relative;\n display: inline-flex;\n min-width: max-content;\n height: var(--control-medium-size);\n padding: 0 var(--control-medium-paddingInline-normal);\n font-size: var(--text-body-size-medium);\n font-weight: var(--base-text-weight-medium);\n color: var(--button-default-fgColor-rest);\n text-align: center;\n cursor: pointer;\n flex-direction: row;\n user-select: none;\n background-color: transparent;\n border: var(--borderWidth-thin) solid;\n border-color: transparent;\n border-radius: var(--borderRadius-medium);\n transition: var(--duration-fast) var(--easing-easeInOut);\n transition-property: color, fill, background-color, border-color;\n justify-content: space-between;\n align-items: center;\n gap: var(--base-size-4);\n\n /* mobile friendly sizing */\n @media (pointer: coarse) {\n &::before {\n @mixin minTouchTarget 48px, 48px;\n }\n }\n\n /* base states */\n\n &:hover {\n transition-duration: var(--duration-fast);\n }\n\n &:active {\n transition: none;\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n cursor: not-allowed;\n box-shadow: none;\n }\n\n &.Button--iconOnly {\n color: var(--fgColor-muted);\n }\n}\n\na.Button,\nsummary.Button {\n &:hover {\n text-decoration: none;\n }\n}\n\n/* wrap grid content to allow trailingAction to lock-right */\n.Button-content {\n flex: 1 0 auto;\n display: grid;\n grid-template-areas: 'leadingVisual text trailingVisual';\n grid-template-columns: min-content minmax(0, auto) min-content;\n align-items: center;\n place-content: center;\n\n /* padding-bottom: 1px; optical alignment for firefox */\n\n & > :not(:last-child) {\n margin-right: var(--control-medium-gap);\n }\n}\n\n/* center child elements for fullWidth */\n.Button-content--alignStart {\n justify-content: start;\n}\n\n/* button child elements */\n\n/* align svg */\n.Button-visual {\n display: flex;\n pointer-events: none; /* allow click handler to work, avoiding visuals */\n\n & .Counter {\n color: inherit;\n background-color: var(--buttonCounter-default-bgColor-rest);\n }\n}\n\n.Button-label {\n line-height: var(--text-body-lineHeight-medium);\n white-space: nowrap;\n grid-area: text;\n}\n\n.Button-leadingVisual {\n grid-area: leadingVisual;\n}\n\n.Button-leadingVisual svg {\n fill: currentcolor;\n}\n\n.Button-trailingVisual {\n grid-area: trailingVisual;\n}\n\n.Button-trailingAction {\n margin-right: calc(var(--base-size-4) * -1);\n}\n\n/* sizes */\n\n.Button--small {\n min-width: var(--control-small-size);\n height: var(--control-small-size);\n padding: 0 var(--control-small-paddingInline-condensed);\n font-size: var(--text-body-size-small);\n gap: var(--control-small-gap);\n\n & .Button-label {\n line-height: var(--text-body-lineHeight-small);\n }\n\n & .Button-content {\n & > :not(:last-child) {\n margin-right: var(--control-small-gap);\n }\n }\n}\n\n.Button--large {\n height: var(--control-large-size);\n padding: 0 var(--control-large-paddingInline-spacious);\n gap: var(--control-large-gap);\n\n & .Button-label {\n line-height: var(--text-body-lineHeight-large);\n }\n\n & .Button-content {\n & > :not(:last-child) {\n margin-right: var(--control-large-gap);\n }\n }\n}\n\n.Button--fullWidth {\n width: 100%;\n}\n\n/* allow button label text to wrap */\n\n.Button--labelWrap {\n min-width: fit-content;\n height: unset;\n min-height: var(--control-medium-size);\n\n & .Button-content {\n flex: 1 1 auto;\n align-self: stretch;\n padding-block: calc(var(--control-medium-paddingBlock) - var(--base-size-2));\n }\n\n & .Button-label {\n white-space: unset;\n }\n\n &.Button--small {\n height: unset;\n min-height: var(--control-small-size);\n\n & .Button-content {\n padding-block: calc(var(--control-small-paddingBlock) - var(--base-size-2));\n }\n }\n\n &.Button--large {\n height: unset;\n min-height: var(--control-large-size);\n padding-inline: var(--control-large-paddingInline-spacious);\n\n & .Button-content {\n padding-block: calc(var(--control-large-paddingBlock) - var(--base-size-2));\n }\n }\n}\n\n/* variants */\n\n/* primary */\n.Button--primary {\n color: var(--button-primary-fgColor-rest);\n fill: var(--button-primary-iconColor-rest);\n background-color: var(--button-primary-bgColor-rest);\n border-color: var(--button-primary-borderColor-rest);\n box-shadow: var(--shadow-resting-small, var(--color-btn-primary-shadow));\n\n &.Button--iconOnly {\n color: var(--button-primary-iconColor-rest);\n }\n\n &:hover:not(:disabled, .Button--inactive) {\n background-color: var(--button-primary-bgColor-hover);\n border-color: var(--button-primary-borderColor-hover);\n }\n\n /* fallback :focus state */\n &:focus {\n @mixin focusOutlineOnEmphasis;\n\n /* remove fallback :focus if :focus-visible is supported */\n &:not(:focus-visible) {\n outline: solid 1px transparent;\n box-shadow: none;\n }\n }\n\n /* default focus state */\n &:focus-visible {\n @mixin focusOutlineOnEmphasis;\n }\n\n &:active:not(:disabled),\n &[aria-pressed='true'] {\n background-color: var(--button-primary-bgColor-active);\n box-shadow: var(--button-primary-shadow-selected);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--button-primary-fgColor-disabled);\n fill: var(--button-primary-fgColor-disabled);\n background-color: var(--button-primary-bgColor-disabled);\n border-color: var(--button-primary-borderColor-disabled);\n }\n\n & .Counter {\n color: inherit;\n background-color: var(--buttonCounter-primary-bgColor-rest);\n }\n}\n\n/* default (secondary) */\n.Button--secondary {\n color: var(--button-default-fgColor-rest);\n fill: var(--fgColor-muted); /* help this */\n background-color: var(--button-default-bgColor-rest);\n border-color: var(--button-default-borderColor-rest);\n box-shadow: var(--button-default-shadow-resting), var(--button-default-shadow-inset);\n\n &:hover:not(:disabled, .Button--inactive) {\n background-color: var(--button-default-bgColor-hover);\n border-color: var(--button-default-borderColor-hover);\n }\n\n &:active:not(:disabled) {\n background-color: var(--button-default-bgColor-active);\n border-color: var(--button-default-borderColor-active);\n }\n\n &[aria-pressed='true'] {\n background-color: var(--button-default-bgColor-selected);\n box-shadow: var(--shadow-inset);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--control-fgColor-disabled);\n fill: var(--control-fgColor-disabled);\n background-color: var(--button-default-bgColor-disabled);\n border-color: var(--button-default-borderColor-disabled);\n }\n}\n\n.Button--invisible {\n color: var(--button-invisible-fgColor-rest);\n\n &.Button--iconOnly {\n color: var(--button-invisible-iconColor-rest, var(--color-fg-muted));\n }\n\n &:hover:not(:disabled, .Button--inactive) {\n background-color: var(--control-transparent-bgColor-hover, var(--color-action-list-item-default-hover-bg));\n }\n\n &[aria-pressed='true'],\n &:active:not(:disabled) {\n background-color: var(--button-invisible-bgColor-active);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--button-invisible-fgColor-disabled);\n fill: var(--button-invisible-fgColor-disabled);\n background-color: var(--button-invisible-bgColor-disabled);\n border-color: var(--button-invisible-borderColor-disabled);\n }\n\n /* if button has no visuals, use link blue for text */\n &.Button--invisible-noVisuals .Button-label {\n color: var(--button-invisible-fgColor-rest);\n }\n\n & .Button-visual {\n color: var(--button-invisible-iconColor-rest, var(--color-fg-muted));\n\n & .Counter {\n color: var(--fgColor-default);\n }\n }\n}\n\n.Button--link {\n display: inline-block;\n min-width: fit-content;\n height: unset;\n padding: 0;\n font-size: inherit;\n color: var(--fgColor-link);\n fill: var(--fgColor-link);\n border: none;\n\n &:hover:not(:disabled, .Button--inactive) {\n text-decoration: underline;\n }\n\n &:focus-visible,\n &:focus {\n outline-offset: 2px;\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--control-fgColor-disabled);\n fill: var(--control-fgColor-disabled);\n background-color: transparent;\n border-color: transparent;\n }\n\n & .Button-label {\n white-space: unset;\n }\n}\n\n/* danger */\n.Button--danger {\n color: var(--button-danger-fgColor-rest);\n fill: var(--button-danger-iconColor-rest);\n background-color: var(--button-danger-bgColor-rest);\n border-color: var(--button-danger-borderColor-rest);\n box-shadow: var(--button-default-shadow-resting), var(--button-default-shadow-inset);\n\n &.Button--iconOnly {\n color: var(--button-danger-iconColor-rest);\n }\n\n &:hover:not(:disabled, .Button--inactive) {\n color: var(--button-danger-fgColor-hover);\n fill: var(--button-danger-fgColor-hover);\n background-color: var(--button-danger-bgColor-hover);\n border-color: var(--button-danger-borderColor-hover);\n box-shadow: var(--shadow-resting-small);\n\n & .Counter {\n color: var(--buttonCounter-danger-fgColor-hover);\n background-color: var(--buttonCounter-danger-bgColor-hover);\n }\n }\n\n &:active:not(:disabled),\n &[aria-pressed='true'] {\n color: var(--button-danger-fgColor-active);\n fill: var(--button-danger-fgColor-active);\n background-color: var(--button-danger-bgColor-active);\n border-color: var(--button-danger-borderColor-active);\n box-shadow: var(--button-danger-shadow-selected);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--button-danger-fgColor-disabled);\n fill: var(--button-danger-fgColor-disabled);\n background-color: var(--button-danger-bgColor-disabled);\n border-color: var(--button-default-borderColor-disabled);\n\n & .Counter {\n color: var(--buttonCounter-danger-fgColor-disabled);\n background-color: var(--buttonCounter-danger-bgColor-disabled);\n }\n }\n\n & .Counter {\n color: var(--buttonCounter-danger-fgColor-rest);\n background-color: var(--buttonCounter-danger-bgColor-rest);\n }\n}\n\n.Button--iconOnly {\n display: inline-grid;\n width: var(--control-medium-size);\n padding: unset;\n place-content: center;\n\n &.Button--small {\n width: var(--control-small-size);\n }\n\n &.Button--large {\n width: var(--control-large-size);\n }\n}\n\n/* `disabled` takes precedence over `inactive` */\n.Button--inactive:not([aria-disabled='true'], :disabled) {\n color: var(--button-inactive-fgColor);\n cursor: default;\n background-color: var(--button-inactive-bgColor);\n border: 0;\n}\n",null,"/* outline with fg box-shadow for buttons */\n@define-mixin focusOutlineOnEmphasis $outlineOffset: -2px, $outlineColor: var(--focus-outlineColor) {\n outline: 2px solid $outlineColor;\n outline-offset: $outlineOffset;\n box-shadow: inset 0 0 0 3px var(--fgColor-onEmphasis);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["button.pcss","<no source>","../../../../lib/postcss_mixins/focusOutlineOnEmphasis.pcss"],"names":[],"mappings":"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","file":"button.css","sourcesContent":["/* stylelint-disable selector-no-qualifying-type */\n/* stylelint-disable selector-max-type */\n/* stylelint-disable primer/spacing */\n\n/* CSS for Button */\n\n/* temporary, pre primitives release */\n:root {\n --duration-fast: 80ms;\n --easing-easeInOut: cubic-bezier(0.65, 0, 0.35, 1);\n}\n\n/* base button */\n.Button {\n position: relative;\n display: inline-flex;\n min-width: max-content;\n height: var(--control-medium-size);\n padding: 0 var(--control-medium-paddingInline-normal);\n font-size: var(--text-body-size-medium);\n font-weight: var(--base-text-weight-medium);\n color: var(--button-default-fgColor-rest);\n text-align: center;\n cursor: pointer;\n flex-direction: row;\n user-select: none;\n background-color: transparent;\n border: var(--borderWidth-thin) solid;\n border-color: transparent;\n border-radius: var(--borderRadius-medium);\n transition: var(--duration-fast) var(--easing-easeInOut);\n transition-property: color, fill, background-color, border-color;\n justify-content: space-between;\n align-items: center;\n gap: var(--base-size-4);\n\n /* mobile friendly sizing */\n @media (pointer: coarse) {\n &::before {\n @mixin minTouchTarget 48px, 48px;\n }\n }\n\n /* base states */\n\n &:hover {\n transition-duration: var(--duration-fast);\n }\n\n &:active {\n transition: none;\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n cursor: not-allowed;\n box-shadow: none;\n }\n\n &.Button--iconOnly {\n color: var(--fgColor-muted);\n }\n}\n\na.Button,\nsummary.Button {\n &:hover {\n text-decoration: none;\n }\n}\n\n/* wrap grid content to allow trailingAction to lock-right */\n.Button-content {\n flex: 1 0 auto;\n display: grid;\n grid-template-areas: 'leadingVisual text trailingVisual';\n grid-template-columns: min-content minmax(0, auto) min-content;\n align-items: center;\n place-content: center;\n\n /* padding-bottom: 1px; optical alignment for firefox */\n\n & > :not(:last-child) {\n margin-right: var(--control-medium-gap);\n }\n}\n\n/* center child elements for fullWidth */\n.Button-content--alignStart {\n justify-content: start;\n}\n\n/* button child elements */\n\n/* align svg */\n.Button-visual {\n display: flex;\n pointer-events: none; /* allow click handler to work, avoiding visuals */\n\n & .Counter {\n color: inherit;\n background-color: var(--buttonCounter-default-bgColor-rest);\n }\n}\n\n.Button-label {\n line-height: var(--text-body-lineHeight-medium);\n white-space: nowrap;\n grid-area: text;\n}\n\n.Button-leadingVisual {\n grid-area: leadingVisual;\n}\n\n.Button-leadingVisual svg {\n fill: currentcolor;\n}\n\n.Button-trailingVisual {\n grid-area: trailingVisual;\n}\n\n.Button-trailingAction {\n margin-right: calc(var(--base-size-4) * -1);\n}\n\n/* sizes */\n\n.Button--small {\n min-width: var(--control-small-size);\n height: var(--control-small-size);\n padding: 0 var(--control-small-paddingInline-condensed);\n font-size: var(--text-body-size-small);\n gap: var(--control-small-gap);\n\n & .Button-label {\n line-height: var(--text-body-lineHeight-small);\n }\n\n & .Button-content {\n & > :not(:last-child) {\n margin-right: var(--control-small-gap);\n }\n }\n}\n\n.Button--large {\n height: var(--control-large-size);\n padding: 0 var(--control-large-paddingInline-spacious);\n gap: var(--control-large-gap);\n\n & .Button-label {\n line-height: var(--text-body-lineHeight-large);\n }\n\n & .Button-content {\n & > :not(:last-child) {\n margin-right: var(--control-large-gap);\n }\n }\n}\n\n.Button--fullWidth {\n width: 100%;\n}\n\n/* allow button label text to wrap */\n\n.Button--labelWrap {\n min-width: fit-content;\n height: unset;\n min-height: var(--control-medium-size);\n\n & .Button-content {\n flex: 1 1 auto;\n align-self: stretch;\n padding-block: calc(var(--control-medium-paddingBlock) - var(--base-size-2));\n }\n\n & .Button-label {\n white-space: unset;\n }\n\n &.Button--small {\n height: unset;\n min-height: var(--control-small-size);\n\n & .Button-content {\n padding-block: calc(var(--control-small-paddingBlock) - var(--base-size-2));\n }\n }\n\n &.Button--large {\n height: unset;\n min-height: var(--control-large-size);\n padding-inline: var(--control-large-paddingInline-spacious);\n\n & .Button-content {\n padding-block: calc(var(--control-large-paddingBlock) - var(--base-size-2));\n }\n }\n}\n\n/* variants */\n\n/* primary */\n.Button--primary {\n color: var(--button-primary-fgColor-rest);\n fill: var(--button-primary-iconColor-rest);\n background-color: var(--button-primary-bgColor-rest);\n border-color: var(--button-primary-borderColor-rest);\n box-shadow: var(--shadow-resting-small, var(--color-btn-primary-shadow));\n\n &.Button--iconOnly {\n color: var(--button-primary-iconColor-rest);\n }\n\n &:hover:not(:disabled, .Button--inactive) {\n background-color: var(--button-primary-bgColor-hover);\n border-color: var(--button-primary-borderColor-hover);\n }\n\n /* fallback :focus state */\n &:focus {\n @mixin focusOutlineOnEmphasis;\n\n /* remove fallback :focus if :focus-visible is supported */\n &:not(:focus-visible) {\n outline: solid 1px transparent;\n box-shadow: none;\n }\n }\n\n /* default focus state */\n &:focus-visible {\n @mixin focusOutlineOnEmphasis;\n }\n\n &:active:not(:disabled),\n &[aria-pressed='true'] {\n background-color: var(--button-primary-bgColor-active);\n box-shadow: var(--button-primary-shadow-selected);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--button-primary-fgColor-disabled);\n fill: var(--button-primary-fgColor-disabled);\n background-color: var(--button-primary-bgColor-disabled);\n border-color: var(--button-primary-borderColor-disabled);\n }\n\n & .Counter {\n color: inherit;\n background-color: var(--buttonCounter-primary-bgColor-rest);\n }\n}\n\n/* default (secondary) */\n.Button--secondary {\n color: var(--button-default-fgColor-rest);\n fill: var(--fgColor-muted); /* help this */\n background-color: var(--button-default-bgColor-rest);\n border-color: var(--button-default-borderColor-rest);\n box-shadow: var(--button-default-shadow-resting), var(--button-default-shadow-inset);\n\n &:hover:not(:disabled, .Button--inactive) {\n background-color: var(--button-default-bgColor-hover);\n border-color: var(--button-default-borderColor-hover);\n }\n\n &:active:not(:disabled) {\n background-color: var(--button-default-bgColor-active);\n border-color: var(--button-default-borderColor-active);\n }\n\n &[aria-pressed='true'] {\n background-color: var(--button-default-bgColor-selected);\n box-shadow: var(--shadow-inset);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--control-fgColor-disabled);\n fill: var(--control-fgColor-disabled);\n background-color: var(--button-default-bgColor-disabled);\n border-color: var(--button-default-borderColor-disabled);\n }\n}\n\n.Button--invisible {\n color: var(--button-invisible-fgColor-rest);\n\n &.Button--iconOnly {\n color: var(--button-invisible-iconColor-rest, var(--color-fg-muted));\n }\n\n &:hover:not(:disabled, .Button--inactive) {\n background-color: var(--control-transparent-bgColor-hover, var(--color-action-list-item-default-hover-bg));\n }\n\n &[aria-pressed='true'],\n &:active:not(:disabled) {\n background-color: var(--button-invisible-bgColor-active);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--button-invisible-fgColor-disabled);\n fill: var(--button-invisible-fgColor-disabled);\n background-color: var(--button-invisible-bgColor-disabled);\n border-color: var(--button-invisible-borderColor-disabled);\n }\n\n /* if button has no visuals, use link blue for text */\n &.Button--invisible-noVisuals .Button-label {\n color: var(--button-invisible-fgColor-rest);\n }\n\n & .Button-visual {\n color: var(--button-invisible-iconColor-rest, var(--color-fg-muted));\n\n & .Counter {\n color: var(--fgColor-default);\n }\n }\n}\n\n.Button--link {\n display: inline-block;\n min-width: fit-content;\n height: unset;\n padding: 0;\n font-size: inherit;\n color: var(--fgColor-link);\n fill: var(--fgColor-link);\n border: none;\n\n &:hover:not(:disabled, .Button--inactive) {\n text-decoration: underline;\n }\n\n &:focus-visible,\n &:focus {\n outline-offset: 2px;\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--control-fgColor-disabled);\n fill: var(--control-fgColor-disabled);\n background-color: transparent;\n border-color: transparent;\n }\n\n & .Button-label {\n white-space: unset;\n }\n}\n\n/* danger */\n.Button--danger {\n color: var(--button-danger-fgColor-rest);\n fill: var(--button-danger-iconColor-rest);\n background-color: var(--button-danger-bgColor-rest);\n border-color: var(--button-danger-borderColor-rest);\n box-shadow: var(--button-default-shadow-resting), var(--button-default-shadow-inset);\n\n &.Button--iconOnly {\n color: var(--button-danger-iconColor-rest);\n }\n\n &:hover:not(:disabled, .Button--inactive) {\n color: var(--button-danger-fgColor-hover);\n fill: var(--button-danger-fgColor-hover);\n background-color: var(--button-danger-bgColor-hover);\n border-color: var(--button-danger-borderColor-hover);\n box-shadow: var(--shadow-resting-small);\n\n & .Counter {\n color: var(--buttonCounter-danger-fgColor-hover);\n background-color: var(--buttonCounter-danger-bgColor-hover);\n }\n }\n\n &:active:not(:disabled),\n &[aria-pressed='true'] {\n color: var(--button-danger-fgColor-active);\n fill: var(--button-danger-fgColor-active);\n background-color: var(--button-danger-bgColor-active);\n border-color: var(--button-danger-borderColor-active);\n box-shadow: var(--button-danger-shadow-selected);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--button-danger-fgColor-disabled);\n fill: var(--button-danger-fgColor-disabled);\n background-color: var(--button-danger-bgColor-disabled);\n border-color: var(--button-default-borderColor-disabled);\n\n & .Counter {\n color: var(--buttonCounter-danger-fgColor-disabled);\n background-color: var(--buttonCounter-danger-bgColor-disabled);\n }\n }\n\n & .Counter {\n color: var(--buttonCounter-danger-fgColor-rest);\n background-color: var(--buttonCounter-danger-bgColor-rest);\n }\n}\n\n.Button--iconOnly {\n display: inline-grid;\n width: var(--control-medium-size);\n padding: unset;\n place-content: center;\n\n &.Button--small {\n width: var(--control-small-size);\n }\n\n &.Button--large {\n width: var(--control-large-size);\n }\n}\n\n/* `disabled` takes precedence over `inactive` */\n.Button--inactive:not([aria-disabled='true'], :disabled) {\n color: var(--button-inactive-fgColor);\n cursor: default;\n background-color: var(--button-inactive-bgColor);\n border: 0;\n}\n",null,"/* outline with fg box-shadow for buttons */\n@define-mixin focusOutlineOnEmphasis $outlineOffset: -2px, $outlineColor: var(--focus-outlineColor) {\n outline: 2px solid $outlineColor;\n outline-offset: $outlineOffset;\n box-shadow: inset 0 0 0 3px var(--fgColor-onEmphasis);\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<%= render(Primer::BaseComponent.new(tag: :span, hidden: @hidden, data: { target: @target }, **@wrapper_arguments)) do %>
|
|
2
2
|
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
|
3
|
-
<circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" fill="none"
|
|
4
|
-
<path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke"
|
|
3
|
+
<circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" fill="none"></circle>
|
|
4
|
+
<path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke"></path>
|
|
5
5
|
<% end %>
|
|
6
6
|
<% if no_aria_label? %>
|
|
7
7
|
<span class="sr-only"><%= @sr_text %></span>
|
|
@@ -22,6 +22,7 @@ import './beta/relative_time';
|
|
|
22
22
|
import './alpha/tab_container';
|
|
23
23
|
import '../../lib/primer/forms/primer_multi_input';
|
|
24
24
|
import '../../lib/primer/forms/primer_text_field';
|
|
25
|
+
import '../../lib/primer/forms/primer_text_area';
|
|
25
26
|
import '../../lib/primer/forms/toggle_switch_input';
|
|
26
27
|
import './alpha/action_menu/action_menu_element';
|
|
27
28
|
import './alpha/select_panel_element';
|
|
@@ -22,6 +22,7 @@ import './beta/relative_time';
|
|
|
22
22
|
import './alpha/tab_container';
|
|
23
23
|
import '../../lib/primer/forms/primer_multi_input';
|
|
24
24
|
import '../../lib/primer/forms/primer_text_field';
|
|
25
|
+
import '../../lib/primer/forms/primer_text_area';
|
|
25
26
|
import '../../lib/primer/forms/toggle_switch_input';
|
|
26
27
|
import './alpha/action_menu/action_menu_element';
|
|
27
28
|
import './alpha/select_panel_element';
|
|
@@ -22,6 +22,7 @@ import './beta/relative_time'
|
|
|
22
22
|
import './alpha/tab_container'
|
|
23
23
|
import '../../lib/primer/forms/primer_multi_input'
|
|
24
24
|
import '../../lib/primer/forms/primer_text_field'
|
|
25
|
+
import '../../lib/primer/forms/primer_text_area'
|
|
25
26
|
import '../../lib/primer/forms/toggle_switch_input'
|
|
26
27
|
import './alpha/action_menu/action_menu_element'
|
|
27
28
|
import './alpha/select_panel_element'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# :nodoc:
|
|
4
|
+
class TextFieldWithCharacterLimitForm < ApplicationForm
|
|
5
|
+
form do |my_form|
|
|
6
|
+
my_form.text_field(
|
|
7
|
+
name: :username,
|
|
8
|
+
label: "Username",
|
|
9
|
+
caption: "Choose a unique username",
|
|
10
|
+
character_limit: 20
|
|
11
|
+
)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
<% if @input.
|
|
2
|
-
<span class="
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<span class="FormControl-caption"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
<% if @input.character_limit? %>
|
|
2
|
+
<span class="sr-only" data-target="<%= @input.character_limit_target_prefix %>.characterLimitSrElement" aria-live="polite" role="status"></span>
|
|
3
|
+
<span class="sr-only" id="<%= @input.character_limit_id %>">You can enter up to <%= @input.character_limit %> <%= @input.character_limit == 1 ? 'character' : 'characters' %></span>
|
|
4
|
+
<span class="FormControl-caption" data-target="<%= @input.character_limit_target_prefix %>.characterLimitElement" data-max-length="<%= @input.character_limit %>" aria-hidden="true">
|
|
5
|
+
<span class="FormControl-caption-icon" hidden><%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %></span>
|
|
6
|
+
<span class="FormControl-caption-text"><%= @input.character_limit %> <%= @input.character_limit == 1 ? 'character' : 'characters' %> remaining</span>
|
|
7
|
+
</span>
|
|
8
|
+
<% end %>
|
|
9
|
+
<% if @input.caption? || caption_template? %>
|
|
10
|
+
<span class="FormControl-caption" id="<%= @input.caption_id %>">
|
|
11
|
+
<% if @input.caption? && !@input.caption.blank? %>
|
|
12
|
+
<%= @input.caption %>
|
|
13
|
+
<% elsif caption_template? %>
|
|
14
|
+
<%= render_caption_template %>
|
|
15
|
+
<% end %>
|
|
16
|
+
</span>
|
|
10
17
|
<% end %>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared character counting functionality for text inputs with character limits.
|
|
3
|
+
* Handles real-time character count updates, validation, and aria-live announcements.
|
|
4
|
+
*/
|
|
5
|
+
export declare class CharacterCounter {
|
|
6
|
+
private inputElement;
|
|
7
|
+
private characterLimitElement;
|
|
8
|
+
private characterLimitSrElement;
|
|
9
|
+
private SCREEN_READER_DELAY;
|
|
10
|
+
private announceTimeout;
|
|
11
|
+
private isInitialLoad;
|
|
12
|
+
constructor(inputElement: HTMLInputElement | HTMLTextAreaElement, characterLimitElement: HTMLElement, characterLimitSrElement: HTMLElement);
|
|
13
|
+
/**
|
|
14
|
+
* Initialize character counting by setting up event listener and initial count
|
|
15
|
+
*/
|
|
16
|
+
initialize(signal?: AbortSignal): void;
|
|
17
|
+
/**
|
|
18
|
+
* Clean up any pending timeouts
|
|
19
|
+
*/
|
|
20
|
+
cleanup(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Pluralizes a word based on the count
|
|
23
|
+
*/
|
|
24
|
+
private pluralize;
|
|
25
|
+
/**
|
|
26
|
+
* Update the character count display and validation state
|
|
27
|
+
*/
|
|
28
|
+
private updateCharacterCount;
|
|
29
|
+
/**
|
|
30
|
+
* Announce character count to screen readers with debouncing
|
|
31
|
+
*/
|
|
32
|
+
private announceToScreenReader;
|
|
33
|
+
/**
|
|
34
|
+
* Set error when character limit is exceeded
|
|
35
|
+
*/
|
|
36
|
+
private setError;
|
|
37
|
+
/**
|
|
38
|
+
* Clear error when back under character limit
|
|
39
|
+
*/
|
|
40
|
+
private clearError;
|
|
41
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared character counting functionality for text inputs with character limits.
|
|
3
|
+
* Handles real-time character count updates, validation, and aria-live announcements.
|
|
4
|
+
*/
|
|
5
|
+
export class CharacterCounter {
|
|
6
|
+
constructor(inputElement, characterLimitElement, characterLimitSrElement) {
|
|
7
|
+
this.inputElement = inputElement;
|
|
8
|
+
this.characterLimitElement = characterLimitElement;
|
|
9
|
+
this.characterLimitSrElement = characterLimitSrElement;
|
|
10
|
+
this.SCREEN_READER_DELAY = 500;
|
|
11
|
+
this.announceTimeout = null;
|
|
12
|
+
this.isInitialLoad = true;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Initialize character counting by setting up event listener and initial count
|
|
16
|
+
*/
|
|
17
|
+
initialize(signal) {
|
|
18
|
+
this.inputElement.addEventListener('keyup', () => this.updateCharacterCount(), signal ? { signal } : undefined); // Keyup used over input for better screen reader support
|
|
19
|
+
this.inputElement.addEventListener('paste', () => setTimeout(() => this.updateCharacterCount(), 50), // Gives the pasted content time to register
|
|
20
|
+
signal ? { signal } : undefined);
|
|
21
|
+
this.updateCharacterCount();
|
|
22
|
+
this.isInitialLoad = false;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Clean up any pending timeouts
|
|
26
|
+
*/
|
|
27
|
+
cleanup() {
|
|
28
|
+
if (this.announceTimeout) {
|
|
29
|
+
clearTimeout(this.announceTimeout);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Pluralizes a word based on the count
|
|
34
|
+
*/
|
|
35
|
+
pluralize(count, string) {
|
|
36
|
+
return count === 1 ? string : `${string}s`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Update the character count display and validation state
|
|
40
|
+
*/
|
|
41
|
+
updateCharacterCount() {
|
|
42
|
+
if (!this.characterLimitElement)
|
|
43
|
+
return;
|
|
44
|
+
const maxLengthAttr = this.characterLimitElement.getAttribute('data-max-length');
|
|
45
|
+
if (!maxLengthAttr)
|
|
46
|
+
return;
|
|
47
|
+
const maxLength = parseInt(maxLengthAttr, 10);
|
|
48
|
+
const currentLength = this.inputElement.value.length;
|
|
49
|
+
const charactersRemaining = maxLength - currentLength;
|
|
50
|
+
let message = '';
|
|
51
|
+
if (charactersRemaining >= 0) {
|
|
52
|
+
const characterText = this.pluralize(charactersRemaining, 'character');
|
|
53
|
+
message = `${charactersRemaining} ${characterText} remaining`;
|
|
54
|
+
const textSpan = this.characterLimitElement.querySelector('.FormControl-caption-text');
|
|
55
|
+
if (textSpan) {
|
|
56
|
+
textSpan.textContent = message;
|
|
57
|
+
}
|
|
58
|
+
this.clearError();
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const charactersOver = -charactersRemaining;
|
|
62
|
+
const characterText = this.pluralize(charactersOver, 'character');
|
|
63
|
+
message = `${charactersOver} ${characterText} over`;
|
|
64
|
+
const textSpan = this.characterLimitElement.querySelector('.FormControl-caption-text');
|
|
65
|
+
if (textSpan) {
|
|
66
|
+
textSpan.textContent = message;
|
|
67
|
+
}
|
|
68
|
+
this.setError();
|
|
69
|
+
}
|
|
70
|
+
// We don't want this announced on initial load
|
|
71
|
+
if (!this.isInitialLoad) {
|
|
72
|
+
this.announceToScreenReader(message);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Announce character count to screen readers with debouncing
|
|
77
|
+
*/
|
|
78
|
+
announceToScreenReader(message) {
|
|
79
|
+
if (this.announceTimeout) {
|
|
80
|
+
clearTimeout(this.announceTimeout);
|
|
81
|
+
}
|
|
82
|
+
this.announceTimeout = window.setTimeout(() => {
|
|
83
|
+
if (this.characterLimitSrElement) {
|
|
84
|
+
this.characterLimitSrElement.textContent = message;
|
|
85
|
+
}
|
|
86
|
+
}, this.SCREEN_READER_DELAY);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Set error when character limit is exceeded
|
|
90
|
+
*/
|
|
91
|
+
setError() {
|
|
92
|
+
this.inputElement.setAttribute('invalid', 'true');
|
|
93
|
+
this.inputElement.setAttribute('aria-invalid', 'true');
|
|
94
|
+
this.characterLimitElement.classList.add('fgColor-danger');
|
|
95
|
+
// Show danger icon
|
|
96
|
+
const icon = this.characterLimitElement.querySelector('.FormControl-caption-icon');
|
|
97
|
+
if (icon) {
|
|
98
|
+
icon.removeAttribute('hidden');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Clear error when back under character limit
|
|
103
|
+
*/
|
|
104
|
+
clearError() {
|
|
105
|
+
this.inputElement.removeAttribute('invalid');
|
|
106
|
+
this.inputElement.removeAttribute('aria-invalid');
|
|
107
|
+
this.characterLimitElement.classList.remove('fgColor-danger');
|
|
108
|
+
// Hide danger icon
|
|
109
|
+
const icon = this.characterLimitElement.querySelector('.FormControl-caption-icon');
|
|
110
|
+
if (icon) {
|
|
111
|
+
icon.setAttribute('hidden', '');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|