primer_view_components 0.0.92 → 0.0.93
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +2 -2
- 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 -0
- data/app/assets/styles/primer_view_components.css.map +1 -1
- data/app/components/primer/alpha/dialog/body.rb +25 -0
- data/app/components/primer/alpha/dialog/footer.rb +31 -0
- data/app/components/primer/alpha/dialog/header.html.erb +15 -0
- data/app/components/primer/alpha/dialog/header.rb +37 -0
- data/app/components/primer/alpha/dialog.html.erb +12 -0
- data/app/components/primer/alpha/dialog.rb +160 -0
- data/app/components/primer/alpha/modal-dialog-element.d.ts +1 -1
- data/app/components/primer/alpha/modal-dialog-element.js +2 -3
- data/app/components/primer/alpha/modal-dialog-element.ts +148 -0
- data/app/components/primer/alpha/toggle-switch-element.js +2 -0
- data/app/components/primer/alpha/toggle-switch-element.ts +2 -1
- data/app/components/primer/alpha/tool-tip-element.ts +0 -1
- data/app/components/primer/beta/button.html.erb +23 -0
- data/app/components/primer/beta/button.pcss +332 -0
- data/app/components/primer/beta/button.rb +189 -0
- data/app/components/primer/beta/icon_button.html.erb +6 -0
- data/app/components/primer/beta/icon_button.rb +104 -0
- data/app/components/primer/clipboard_copy_component.ts +1 -1
- data/app/components/primer/experimental/action-bar-element.d.ts +14 -0
- data/app/components/primer/experimental/action-bar-element.js +139 -0
- data/app/components/primer/experimental/action-menu-element.d.ts +31 -0
- data/app/components/primer/experimental/action-menu-element.js +334 -0
- data/app/components/primer/experimental/overflow-menu-element.d.ts +13 -0
- data/app/components/primer/experimental/overflow-menu-element.js +113 -0
- data/app/components/primer/primer.d.ts +1 -0
- data/app/components/primer/primer.js +1 -0
- data/app/components/primer/primer.pcss +1 -0
- data/app/components/primer/primer.ts +1 -0
- data/lib/postcss_mixins/focusBoxShadowInset.pcss +6 -0
- data/lib/postcss_mixins/focusOutline.pcss +5 -0
- data/lib/postcss_mixins/focusOutlineOnEmphasis.pcss +6 -0
- data/lib/postcss_mixins/minTouchTarget.js +20 -0
- data/lib/postcss_mixins/targetBoxShadow.pcss +6 -0
- data/lib/primer/view_components/linters/argument_mappers/base.rb +1 -1
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/tasks/docs.rake +3 -8
- data/static/arguments.yml +113 -0
- data/static/audited_at.json +6 -0
- data/static/constants.json +107 -0
- data/static/statuses.json +6 -0
- metadata +25 -5
- data/app/components/primer/alpha/segmented-control-element.d.ts +0 -8
- data/app/components/primer/alpha/segmented-control-element.js +0 -28
- data/static/classes.yml +0 -230
@@ -0,0 +1 @@
|
|
1
|
+
:root{--primer-duration-fast:80ms;--primer-easing-easeInOut:cubic-bezier(0.65,0,0.35,1)}.Button{align-items:center;background-color:transparent;border:1px solid;border:var(--primer-borderWidth-thin,1px) solid;border-color:transparent;border-radius:6px;border-radius:var(--primer-borderRadius-medium,6px);color:var(--color-btn-text);cursor:pointer;display:flex;flex-direction:row;font-size:14px;font-size:var(--primer-text-body-size-medium,14px);font-weight:500;font-weight:var(--base-text-weight-medium,500);gap:8px;gap:var(--primer-control-medium-gap,8px);height:32px;height:var(--primer-control-medium-size,32px);justify-content:space-between;padding:0 12px;padding:0 var(--primer-control-medium-paddingInline-normal,12px);position:relative;text-align:center;transition:80ms cubic-bezier(.65,0,.35,1);transition:var(--primer-duration-fast) var(--primer-easing-easeInOut);transition-property:color,fill,background-color,border-color;-webkit-user-select:none;-moz-user-select:none;user-select:none}@media (pointer:course){.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:80ms;transition-duration:var(--primer-duration-fast)}.Button.Button--active,.Button:active{transition:none}.Button.Button--disabled,.Button:disabled,.Button[aria-disabled=true]{box-shadow:none;cursor:not-allowed}.Button-withTooltip{display:inline-block;position:relative}a.Button,summary.Button{display:inline-flex}a.Button:hover,summary.Button:hover{text-decoration:none}.Button-content{align-items:center;display:grid;flex:1 0 auto;grid-template-areas:"leadingVisual text trailingVisual";grid-template-columns:-webkit-min-content minmax(0,auto) -webkit-min-content;grid-template-columns:min-content minmax(0,auto) min-content;place-content:center}.Button-content>:not(:last-child){margin-right:8px;margin-right:var(--primer-control-medium-gap,8px)}.Button-content--alignStart{justify-content:start}.Button-visual{display:flex;pointer-events:none}.Button-label{grid-area:text;line-height:1.42857;line-height:var(--primer-text-body-lineHeight-medium,1.42857);white-space:nowrap}.Button-leadingVisual{grid-area:leadingVisual}.Button-trailingVisual{grid-area:trailingVisual}.Button-trailingAction{margin-right:-4px;margin-right:calc(var(--base-size-4, 4px)*-1)}.Button--small{font-size:12px;font-size:var(--primer-text-body-size-small,12px);gap:4px;gap:var(--primer-control-small-gap,4px);height:28px;height:var(--primer-control-small-size,28px);padding:0 12px;padding:0 var(--primer-control-small-paddingInline-normal,12px);.Button-label{line-height:1.66667;line-height:var(--primer-text-body-lineHeight-small,1.66667)}.Button-content>:not(:last-child){margin-right:4px;margin-right:var(--primer-control-small-gap,4px)}}.Button--large{gap:8px;gap:var(--primer-control-large-gap,8px);height:40px;height:var(--primer-control-large-size,40px);padding:0 12px;padding:0 var(--primer-control-large-paddingInline-normal,12px);.Button-label{line-height:1.5;line-height:var(--primer-text-body-lineHeight-large,1.5)}.Button-content>:not(:last-child){margin-right:8px;margin-right:var(--primer-control-large-gap,8px)}}.Button--fullWidth{width:100%}.Button--primary{fill:var(--color-btn-primary-icon);background-color:var(--color-btn-primary-bg);border-color:var(--color-btn-primary-border);box-shadow:var(--color-btn-primary-shadow),var(--color-btn-primary-inset-shadow);color:var(--color-btn-primary-text)}.Button--primary:hover{background-color:var(--color-btn-primary-hover-bg);border-color:var(--color-btn-primary-hover-border)}.Button--primary:focus{box-shadow:inset 0 0 0 3px var(--color-fg-on-emphasis);outline:2px solid var(--color-accent-fg);outline-offset:-2px}.Button--primary:focus:not(:focus-visible){box-shadow:none;outline:1px solid transparent}.Button--primary:focus-visible{box-shadow:inset 0 0 0 3px var(--color-fg-on-emphasis);outline:2px solid var(--color-accent-fg);outline-offset:-2px}.Button--primary.Button--pressed,.Button--primary:active,.Button--primary[aria-pressed=true]{background-color:var(--color-btn-primary-selected-bg);box-shadow:var(--color-btn-primary-selected-shadow)}.Button--primary.Button--disabled,.Button--primary:disabled,.Button--primary[aria-disabled=true]{fill:var(--color-btn-primary-disabled-text);background-color:var(--color-btn-primary-disabled-bg);border-color:var(--color-btn-primary-disabled-border);color:var(--color-btn-primary-disabled-text)}.Button--secondary{fill:var(--color-fg-muted);background-color:var(--color-btn-bg);border-color:var(--color-btn-border);box-shadow:var(--color-btn-shadow),var(--color-btn-inset-shadow);color:var(--color-btn-text)}.Button--secondary:hover{background-color:var(--color-btn-hover-bg);border-color:var(--color-btn-hover-border)}.Button--secondary.Button--active,.Button--secondary:active{background-color:var(--color-btn-active-bg);border-color:var(--color-btn-active-border)}.Button--secondary.Button--pressed,.Button--secondary[aria-pressed=true]{background-color:var(--color-btn-selected-bg);box-shadow:var(--color-primer-shadow-inset)}.Button--secondary.Button--disabled,.Button--secondary:disabled,.Button--secondary[aria-disabled=true]{fill:var(--color-primer-fg-disabled);background-color:var(--color-btn-bg);border-color:var(--color-btn-border);color:var(--color-primer-fg-disabled)}.Button--invisible{fill:var(--color-fg-default);border:none;color:var(--color-fg-default)}.Button--invisible:hover{background-color:var(--color-action-list-item-default-hover-bg)}.Button--invisible.Button--active,.Button--invisible.Button--pressed,.Button--invisible:active,.Button--invisible[aria-pressed=true]{background-color:var(--color-action-list-item-default-active-bg)}.Button--invisible.Button--disabled,.Button--invisible:disabled,.Button--invisible[aria-disabled=true]{fill:var(--color-primer-fg-disabled);background-color:var(--color-btn-bg);border-color:var(--color-btn-border);color:var(--color-primer-fg-disabled)}.Button--invisible{.Button-label:not(:only-child){color:var(--color-btn-text)}.Button-content:not(:only-child){.Button-label{color:var(--color-btn-text)}}}.Button--danger{fill:var(--color-btn-danger-icon);background-color:var(--color-btn-bg);border-color:var(--color-btn-border);box-shadow:var(--color-btn-shadow),var(--color-btn-inset-shadow);color:var(--color-btn-danger-text)}.Button--danger:hover{fill:var(--color-btn-danger-hover-text);background-color:var(--color-btn-danger-hover-bg);border-color:var(--color-btn-danger-hover-border);box-shadow:var(--color-btn-danger-hover-shadow),var(--color-btn-danger-hover-inset-shadow);color:var(--color-btn-danger-hover-text)}.Button--danger.Button--pressed,.Button--danger:active,.Button--danger[aria-pressed=true]{fill:var(--color-btn-danger-selected-text);background-color:var(--color-btn-danger-selected-bg);border-color:var(--color-btn-danger-selected-border);box-shadow:var(--color-btn-danger-selected-shadow);color:var(--color-btn-danger-selected-text)}.Button--danger.disabled,.Button--danger:disabled,.Button--danger[aria-disabled=true]{fill:var(--color-btn-danger-disabled-text);background-color:var(--color-btn-danger-disabled-bg);border-color:var(--color-btn-border);color:var(--color-btn-danger-disabled-text)}.Button--iconOnly{display:grid;padding:initial;place-content:center;width:32px;width:var(--primer-control-medium-size,32px)}.Button--iconOnly.Button--small{width:28px;width:var(--primer-control-small-size,28px)}.Button--iconOnly.Button--large{width:40px;width:var(--primer-control-large-size,40px)}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"primer_view_components.css"}
|
1
|
+
{"version":3,"sources":["../../components/primer/beta/button.pcss","<no source>","../../../lib/postcss_mixins/focusOutlineOnEmphasis.pcss"],"names":[],"mappings":"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","file":"primer_view_components.css","sourcesContent":["/* CSS for Button */\n/* temporary, pre primitives release */\n:root {\n --primer-duration-fast: 80ms;\n --primer-easing-easeInOut: cubic-bezier(0.65, 0, 0.35, 1);\n}\n\n/* base button */\n.Button {\n position: relative;\n font-size: var(--primer-text-body-size-medium, 14px);\n font-weight: var(--base-text-weight-medium, 500);\n cursor: pointer;\n user-select: none;\n background-color: transparent;\n border: var(--primer-borderWidth-thin, 1px) solid;\n border-color: transparent;\n border-radius: var(--primer-borderRadius-medium, 6px);\n color: var(--color-btn-text);\n transition: var(--primer-duration-fast) var(--primer-easing-easeInOut);\n transition-property: color, fill, background-color, border-color;\n text-align: center;\n height: var(--primer-control-medium-size, 32px);\n padding: 0 var(--primer-control-medium-paddingInline-normal, 12px);\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n gap: var(--primer-control-medium-gap, 8px);\n\n /* mobile friendly sizing */\n @media (pointer: course) {\n &::before {\n @mixin minTouchTarget 48px, 48px;\n }\n }\n\n /* base states */\n\n &:hover {\n transition-duration: var(--primer-duration-fast);\n }\n\n &:active,\n &.Button--active {\n transition: none;\n }\n\n &:disabled,\n &.Button--disabled,\n &[aria-disabled='true'] {\n cursor: not-allowed;\n box-shadow: none;\n }\n\n /* &:focus {\n @mixin focusOutline;\n } */\n}\n\n.Button-withTooltip {\n position: relative;\n display: inline-block;\n}\n\na.Button,\nsummary.Button {\n display: inline-flex;\n\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 /* padding-bottom: 1px; optical alignment for firefox */\n\n & > :not(:last-child) {\n margin-right: var(--primer-control-medium-gap, 8px);\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\n.Button-label {\n grid-area: text;\n white-space: nowrap;\n line-height: var(--primer-text-body-lineHeight-medium, calc(20/14));\n}\n\n.Button-leadingVisual {\n grid-area: leadingVisual;\n}\n\n.Button-trailingVisual {\n grid-area: trailingVisual;\n}\n\n.Button-trailingAction {\n margin-right: calc(var(--base-size-4, 4px) * -1);\n}\n\n/* sizes */\n\n.Button--small {\n font-size: var(--primer-text-body-size-small, 12px);\n height: var(--primer-control-small-size, 28px);\n padding: 0 var(--primer-control-small-paddingInline-normal, 12px);\n gap: var(--primer-control-small-gap, 4px);\n\n .Button-label {\n line-height: var(--primer-text-body-lineHeight-small, calc(20/12));\n }\n\n .Button-content {\n & > :not(:last-child) {\n margin-right: var(--primer-control-small-gap, 4px);\n }\n }\n}\n\n.Button--large {\n height: var(--primer-control-large-size, 40px);\n padding: 0 var(--primer-control-large-paddingInline-normal, 12px);\n gap: var(--primer-control-large-gap, 8px);\n\n .Button-label {\n line-height: var(--primer-text-body-lineHeight-large, calc(48/32));\n }\n\n .Button-content {\n & > :not(:last-child) {\n margin-right: var(--primer-control-large-gap, 8px);\n }\n }\n}\n\n.Button--fullWidth {\n width: 100%;\n}\n\n/* variants */\n\n/* primary */\n.Button--primary {\n color: var(--color-btn-primary-text);\n fill: var(--color-btn-primary-icon);\n background-color: var(--color-btn-primary-bg);\n border-color: var(--color-btn-primary-border);\n box-shadow: var(--color-btn-primary-shadow), var(--color-btn-primary-inset-shadow);\n\n &:hover {\n background-color: var(--color-btn-primary-hover-bg);\n border-color: var(--color-btn-primary-hover-border);\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,\n &[aria-pressed='true'],\n &.Button--pressed {\n background-color: var(--color-btn-primary-selected-bg);\n box-shadow: var(--color-btn-primary-selected-shadow);\n }\n\n &:disabled,\n &.Button--disabled,\n &[aria-disabled='true'] {\n color: var(--color-btn-primary-disabled-text);\n background-color: var(--color-btn-primary-disabled-bg);\n border-color: var(--color-btn-primary-disabled-border);\n fill: var(--color-btn-primary-disabled-text);\n }\n}\n\n/* default (secondary) */\n.Button--secondary {\n color: var(--color-btn-text);\n fill: var(--color-fg-muted); /* help this */\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n box-shadow: var(--color-btn-shadow), var(--color-btn-inset-shadow);\n\n &:hover {\n background-color: var(--color-btn-hover-bg);\n border-color: var(--color-btn-hover-border);\n }\n\n &:active,\n &.Button--active {\n background-color: var(--color-btn-active-bg);\n border-color: var(--color-btn-active-border);\n }\n\n &[aria-pressed='true'],\n &.Button--pressed {\n background-color: var(--color-btn-selected-bg);\n box-shadow: var(--color-primer-shadow-inset);\n }\n\n &:disabled,\n &.Button--disabled,\n &[aria-disabled='true'] {\n color: var(--color-primer-fg-disabled);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n fill: var(--color-primer-fg-disabled);\n }\n}\n\n/* link color without svg */\n.Button--invisible {\n color: var(--color-fg-default);\n fill: var(--color-fg-default);\n border: none;\n\n &:hover {\n background-color: var(--color-action-list-item-default-hover-bg);\n }\n\n &[aria-pressed='true'],\n &:active,\n &.Button--active,\n &.Button--pressed {\n background-color: var(--color-action-list-item-default-active-bg);\n /* box-shadow: var(--color-primer-shadow-inset); */\n }\n\n &:disabled,\n &.Button--disabled,\n &[aria-disabled='true'] {\n color: var(--color-primer-fg-disabled);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n fill: var(--color-primer-fg-disabled);\n }\n\n /* if visual is present, muted label color */\n .Button-label:not(:only-child) {\n color: var(--color-btn-text);\n }\n\n /* if trailingAction is present, muted label color */\n .Button-content:not(:only-child) {\n .Button-label {\n color: var(--color-btn-text);\n }\n }\n}\n\n/* danger */\n.Button--danger {\n color: var(--color-btn-danger-text);\n fill: var(--color-btn-danger-icon);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n box-shadow: var(--color-btn-shadow), var(--color-btn-inset-shadow);\n\n &:hover {\n color: var(--color-btn-danger-hover-text);\n fill: var(--color-btn-danger-hover-text);\n background-color: var(--color-btn-danger-hover-bg);\n border-color: var(--color-btn-danger-hover-border);\n box-shadow: var(--color-btn-danger-hover-shadow), var(--color-btn-danger-hover-inset-shadow);\n }\n\n &:active,\n &[aria-pressed='true'],\n &.Button--pressed {\n color: var(--color-btn-danger-selected-text);\n fill: var(--color-btn-danger-selected-text);\n background-color: var(--color-btn-danger-selected-bg);\n border-color: var(--color-btn-danger-selected-border);\n box-shadow: var(--color-btn-danger-selected-shadow);\n }\n\n &:disabled,\n &.disabled,\n &[aria-disabled='true'] {\n color: var(--color-btn-danger-disabled-text);\n fill: var(--color-btn-danger-disabled-text);\n background-color: var(--color-btn-danger-disabled-bg);\n border-color: var(--color-btn-border);\n }\n}\n\n.Button--iconOnly {\n display: grid;\n place-content: center;\n padding: unset;\n width: var(--primer-control-medium-size, 32px);\n\n &.Button--small {\n width: var(--primer-control-small-size, 28px);\n }\n\n &.Button--large {\n width: var(--primer-control-large-size, 40px);\n }\n}\n",null,"/* outline with fg box-shadow for buttons */\n@define-mixin focusOutlineOnEmphasis $outlineOffset: -2px, $outlineColor: var(--color-accent-fg) {\n outline: 2px solid $outlineColor;\n outline-offset: $outlineOffset;\n box-shadow: inset 0 0 0 3px var(--color-fg-on-emphasis);\n}\n"]}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Alpha
|
5
|
+
class Dialog
|
6
|
+
# A `Dialog::Body` is a compositional component, used to render the
|
7
|
+
# Body of a dialog. See <%= link_to_component(Primer::Alpha::Dialog) %>.
|
8
|
+
class Body < Primer::Component
|
9
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
10
|
+
def initialize(**system_arguments)
|
11
|
+
@system_arguments = deny_tag_argument(**system_arguments)
|
12
|
+
@system_arguments[:tag] = :div
|
13
|
+
@system_arguments[:classes] = class_names(
|
14
|
+
"Overlay-body",
|
15
|
+
system_arguments[:classes]
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { content }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Alpha
|
5
|
+
class Dialog
|
6
|
+
# A `Dialog::Footer` is a compositional component, used to render the
|
7
|
+
# Footer of a dialog. See <%= link_to_component(Primer::Alpha::Dialog) %>.
|
8
|
+
class Footer < Primer::Component
|
9
|
+
# @param show_divider [Boolean] Show a divider between the footer and body.
|
10
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
11
|
+
def initialize(
|
12
|
+
show_divider: false,
|
13
|
+
**system_arguments
|
14
|
+
)
|
15
|
+
@system_arguments = deny_tag_argument(**system_arguments)
|
16
|
+
@system_arguments[:tag] = :div
|
17
|
+
@system_arguments[:classes] = class_names(
|
18
|
+
"Overlay-footer",
|
19
|
+
"Overlay-footer--alignEnd",
|
20
|
+
{ "Overlay-footer--divided": show_divider },
|
21
|
+
system_arguments[:classes]
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def call
|
26
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { content }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
2
|
+
<div class="Overlay-headerContentWrap">
|
3
|
+
<div class="Overlay-titleWrap">
|
4
|
+
<h1 class="Overlay-title <% if @visually_hide_title || content.present? %>sr-only<% end %>"><%= @title %></h1>
|
5
|
+
<% if content.present? %>
|
6
|
+
<%= content %>
|
7
|
+
<% elsif @subtitle.present? %>
|
8
|
+
<h2 id="<%= @id %>-description" class="Overlay-description"><%= @subtitle %></h2>
|
9
|
+
<% end %>
|
10
|
+
</div>
|
11
|
+
<div class="Overlay-actionWrap">
|
12
|
+
<%= render Primer::Beta::CloseButton.new(classes: "Overlay-closeButton", "data-close-dialog-id": @id) %>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
<% end %>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Alpha
|
5
|
+
class Dialog
|
6
|
+
# A `Dialog::Header` is a compositional component, used to render the
|
7
|
+
# Header of a dialog. See <%= link_to_component(Primer::Alpha::Dialog) %>.
|
8
|
+
class Header < Primer::Component
|
9
|
+
# @param title [String] Describes the content of the dialog.
|
10
|
+
# @param subtitle [String] Provides dditional context for the dialog, also setting the `aria-describedby` attribute.
|
11
|
+
# @param show_divider [Boolean] Show a divider between the header and body.
|
12
|
+
# @param visually_hide_title [Boolean] Visually hide the `title` while maintaining a label for assistive technologies.
|
13
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
14
|
+
def initialize(
|
15
|
+
id:,
|
16
|
+
title:,
|
17
|
+
subtitle: nil,
|
18
|
+
show_divider: false,
|
19
|
+
visually_hide_title: false,
|
20
|
+
**system_arguments
|
21
|
+
)
|
22
|
+
@id = id
|
23
|
+
@title = title
|
24
|
+
@subtitle = subtitle
|
25
|
+
@visually_hide_title = visually_hide_title
|
26
|
+
@system_arguments = deny_tag_argument(**system_arguments)
|
27
|
+
@system_arguments[:tag] = :header
|
28
|
+
@system_arguments[:classes] = class_names(
|
29
|
+
"Overlay-header",
|
30
|
+
{ "Overlay-header--divided": show_divider },
|
31
|
+
system_arguments[:classes]
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= show_button %>
|
2
|
+
<div class="Overlay--hidden <%= @backdrop_classes %>" data-modal-dialog-overlay>
|
3
|
+
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
4
|
+
<%= header %>
|
5
|
+
<% if content.present? %>
|
6
|
+
<%= content %>
|
7
|
+
<% else %>
|
8
|
+
<%= body %>
|
9
|
+
<%= footer %>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Alpha
|
5
|
+
# A `Dialog` is used to remove the user from the main application flow,
|
6
|
+
# to confirm actions, ask for disambiguation or to present small forms.
|
7
|
+
#
|
8
|
+
# @accessibility
|
9
|
+
# - **Dialog Accessible Name**: A dialog should have an accessible name,
|
10
|
+
# so screen readers are aware of the purpose of the dialog when it opens.
|
11
|
+
# Give an accessible name setting `:title`. The accessible name will be
|
12
|
+
# used as the main heading inside the dialog.
|
13
|
+
# - **Dialog unique id**: A dialog should be unique. Give a unique id
|
14
|
+
# setting `:dialog_id`. If no `:dialog_id` is given, a default randomize
|
15
|
+
# hex id is generated.
|
16
|
+
#
|
17
|
+
# The combination of both `:title` and `:dialog_id` establishes an
|
18
|
+
# `aria-labelledby` relationship between the title and the unique id of
|
19
|
+
# the dialog.
|
20
|
+
class Dialog < Primer::Component
|
21
|
+
DEFAULT_SIZE = :medium
|
22
|
+
SIZE_MAPPINGS = {
|
23
|
+
:small => "Overlay--size-small-portrait",
|
24
|
+
:medium_portrait => "Overlay--size-medium-portrait",
|
25
|
+
DEFAULT_SIZE => "Overlay--size-medium",
|
26
|
+
:large => "Overlay--size-large",
|
27
|
+
:xlarge => "Overlay--size-xlarge"
|
28
|
+
}.freeze
|
29
|
+
SIZE_OPTIONS = SIZE_MAPPINGS.keys
|
30
|
+
|
31
|
+
DEFAULT_POSITION = :center
|
32
|
+
POSITION_MAPPINGS = {
|
33
|
+
DEFAULT_POSITION => "Overlay-backdrop--center",
|
34
|
+
:left => "Overlay-backdrop--side Overlay-backdrop--placement-left",
|
35
|
+
:right => "Overlay-backdrop--side Overlay-backdrop--placement-right"
|
36
|
+
}.freeze
|
37
|
+
POSITION_OPTIONS = POSITION_MAPPINGS.keys
|
38
|
+
|
39
|
+
DEFAULT_POSITION_NARROW = :inherit
|
40
|
+
POSITION_NARROW_MAPPINGS = {
|
41
|
+
DEFAULT_POSITION_NARROW => "",
|
42
|
+
:bottom => "Overlay-backdrop--side-whenNarrow Overlay-backdrop--placement-bottom-whenNarrow",
|
43
|
+
:fullscreen => "Overlay-backdrop--full-whenNarrow",
|
44
|
+
:left => "Overlay-backdrop--side-whenNarrow Overlay-backdrop--placement-left-whenNarrow",
|
45
|
+
:right => "Overlay-backdrop--side-whenNarrow Overlay-backdrop--placement-right-whenNarrow"
|
46
|
+
}.freeze
|
47
|
+
POSITION_NARROW_OPTIONS = POSITION_NARROW_MAPPINGS.keys
|
48
|
+
|
49
|
+
# Optional button to open the dialog.
|
50
|
+
#
|
51
|
+
# @param system_arguments [Hash] The same arguments as <%= link_to_component(Primer::ButtonComponent) %>.
|
52
|
+
renders_one :show_button, lambda { |**system_arguments|
|
53
|
+
system_arguments[:classes] = class_names(
|
54
|
+
system_arguments[:classes]
|
55
|
+
)
|
56
|
+
system_arguments[:id] = "dialog-show-#{@system_arguments[:id]}"
|
57
|
+
system_arguments["data-show-dialog-id"] = @system_arguments[:id]
|
58
|
+
system_arguments[:data] = (system_arguments[:data] || {}).merge({ "show-dialog-id": @system_arguments[:id] })
|
59
|
+
Primer::ButtonComponent.new(**system_arguments)
|
60
|
+
}
|
61
|
+
|
62
|
+
# Header content.
|
63
|
+
#
|
64
|
+
# @param show_divider [Boolean] Show a divider between the header and body.
|
65
|
+
# @param visually_hide_title [Boolean] Visually hide the `title` while maintaining a label for assistive technologies.
|
66
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
67
|
+
renders_one :header, lambda { |show_divider: false, visually_hide_title: @visually_hide_title, **system_arguments|
|
68
|
+
Primer::Alpha::Dialog::Header.new(
|
69
|
+
id: @id,
|
70
|
+
title: @title,
|
71
|
+
subtitle: @subtitle,
|
72
|
+
show_divider: show_divider,
|
73
|
+
visually_hide_title: visually_hide_title,
|
74
|
+
**system_arguments
|
75
|
+
)
|
76
|
+
}
|
77
|
+
|
78
|
+
# Required body content.
|
79
|
+
#
|
80
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
81
|
+
renders_one :body, "Body"
|
82
|
+
|
83
|
+
# Footer content.
|
84
|
+
#
|
85
|
+
# @param show_divider [Boolean] Show a divider between the footer and body.
|
86
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
87
|
+
renders_one :footer, "Footer"
|
88
|
+
|
89
|
+
# @example Dialog with Cancel and Submit buttons
|
90
|
+
# @description
|
91
|
+
# An ID is provided which enables wiring of the open and close buttons to the dialog.
|
92
|
+
# @code
|
93
|
+
# <%= render(Primer::Alpha::Dialog.new(
|
94
|
+
# title: "Dialog Example",
|
95
|
+
# id: "my-dialog",
|
96
|
+
# )) do |d| %>
|
97
|
+
# <% d.with_show_button { "Show Dialog" } %>
|
98
|
+
# <% d.with_body do %>
|
99
|
+
# <p>Some content</p>
|
100
|
+
# <% end %>
|
101
|
+
# <% d.footer do %>
|
102
|
+
# <%= render(Primer::ButtonComponent.new(data: { "close-dialog-id": "my-dialog" })) { "Cancel" } %>
|
103
|
+
# <%= render(Primer::ButtonComponent.new(scheme: :primary)) { "Submit" } %>
|
104
|
+
# <% end %>
|
105
|
+
# <% end %>
|
106
|
+
# @param id [String] The id of the dialog.
|
107
|
+
# @param title [String] Describes the content of the dialog.
|
108
|
+
# @param subtitle [String] Provides dditional context for the dialog, also setting the `aria-describedby` attribute.
|
109
|
+
# @param size [Symbol] The size of the dialog. <%= one_of(Primer::Alpha::Dialog::SIZE_OPTIONS) %>
|
110
|
+
# @param position [Symbol] The size of the dialog. <%= one_of(Primer::Alpha::Dialog::POSITION_OPTIONS) %>
|
111
|
+
# @param position_narrow [Symbol] The size of the dialog. <%= one_of(Primer::Alpha::Dialog::POSITION_NARROW_OPTIONS) %>
|
112
|
+
# @param visually_hide_title [Boolean] If true will hide the heading title, while still making it available to Screen Readers.
|
113
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
114
|
+
def initialize(
|
115
|
+
title:,
|
116
|
+
subtitle: nil,
|
117
|
+
size: DEFAULT_SIZE,
|
118
|
+
position: DEFAULT_POSITION,
|
119
|
+
position_narrow: DEFAULT_POSITION_NARROW,
|
120
|
+
visually_hide_title: false,
|
121
|
+
id: "dialog-#{(36**3 + rand(36**4)).to_s(36)}",
|
122
|
+
**system_arguments
|
123
|
+
)
|
124
|
+
@system_arguments = deny_tag_argument(**system_arguments)
|
125
|
+
|
126
|
+
@system_arguments[:tag] = "modal-dialog"
|
127
|
+
@system_arguments[:role] = "dialog"
|
128
|
+
@system_arguments[:id] = id.to_s
|
129
|
+
@system_arguments[:aria] = { modal: true }
|
130
|
+
@system_arguments[:classes] = class_names(
|
131
|
+
"Overlay",
|
132
|
+
"Overlay-whenNarrow",
|
133
|
+
SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)],
|
134
|
+
"Overlay--motion-scaleFade",
|
135
|
+
system_arguments[:classes]
|
136
|
+
)
|
137
|
+
@backdrop_classes = class_names(
|
138
|
+
POSITION_MAPPINGS[fetch_or_fallback(POSITION_OPTIONS, position, DEFAULT_POSITION)],
|
139
|
+
POSITION_NARROW_MAPPINGS[fetch_or_fallback(POSITION_NARROW_MAPPINGS, position_narrow, DEFAULT_POSITION_NARROW)]
|
140
|
+
)
|
141
|
+
|
142
|
+
@id = id.to_s
|
143
|
+
@title = title
|
144
|
+
@position = position
|
145
|
+
@position_narrow = position_narrow
|
146
|
+
@visually_hide_title = visually_hide_title
|
147
|
+
|
148
|
+
@subtitle = subtitle
|
149
|
+
|
150
|
+
@system_arguments[:aria] ||= {}
|
151
|
+
@system_arguments[:aria][:describedby] ||= "#{@id}-description"
|
152
|
+
end
|
153
|
+
|
154
|
+
def before_render
|
155
|
+
with_header unless header?
|
156
|
+
with_body unless body?
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -92,7 +92,6 @@ export class ModalDialogElement extends HTMLElement {
|
|
92
92
|
}
|
93
93
|
dialogId = button.getAttribute('data-show-dialog-id');
|
94
94
|
if (dialogId === this.id) {
|
95
|
-
//TODO: see if I can remove this
|
96
95
|
event.stopPropagation();
|
97
96
|
__classPrivateFieldSet(this, _ModalDialogElement_openButton, button, "f");
|
98
97
|
this.show();
|
@@ -107,10 +106,10 @@ export class ModalDialogElement extends HTMLElement {
|
|
107
106
|
show() {
|
108
107
|
this.open = true;
|
109
108
|
}
|
110
|
-
close(
|
109
|
+
close(closedNotCancelled = false) {
|
111
110
|
if (this.open === false)
|
112
111
|
return;
|
113
|
-
const eventType =
|
112
|
+
const eventType = closedNotCancelled ? 'close' : 'cancel';
|
114
113
|
const dialogEvent = new Event(eventType);
|
115
114
|
this.dispatchEvent(dialogEvent);
|
116
115
|
this.open = false;
|
@@ -0,0 +1,148 @@
|
|
1
|
+
import {focusTrap} from '@primer/behaviors'
|
2
|
+
import {getFocusableChild} from '@primer/behaviors/utils'
|
3
|
+
|
4
|
+
function focusIfNeeded(elem?: HTMLElement) {
|
5
|
+
if (document.activeElement !== elem) {
|
6
|
+
elem?.focus()
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
export class ModalDialogElement extends HTMLElement {
|
11
|
+
//TODO: Do we remove the abortController from focusTrap?
|
12
|
+
#focusAbortController = new AbortController()
|
13
|
+
#abortController: AbortController | null = null
|
14
|
+
#openButton: HTMLButtonElement | undefined
|
15
|
+
#shouldTryLoadingFragment = true
|
16
|
+
|
17
|
+
get open() {
|
18
|
+
return this.hasAttribute('open')
|
19
|
+
}
|
20
|
+
set open(value: boolean) {
|
21
|
+
if (value) {
|
22
|
+
if (this.open) return
|
23
|
+
this.setAttribute('open', '')
|
24
|
+
this.#overlayBackdrop?.classList.remove('Overlay--hidden')
|
25
|
+
document.body.style.overflow = 'hidden'
|
26
|
+
if (this.#focusAbortController.signal.aborted) {
|
27
|
+
this.#focusAbortController = new AbortController()
|
28
|
+
}
|
29
|
+
focusTrap(this, undefined, this.#focusAbortController.signal)
|
30
|
+
} else {
|
31
|
+
if (!this.open) return
|
32
|
+
this.removeAttribute('open')
|
33
|
+
this.#overlayBackdrop?.classList.add('Overlay--hidden')
|
34
|
+
document.body.style.overflow = 'initial'
|
35
|
+
this.#focusAbortController.abort()
|
36
|
+
// if #openButton is a child of a menu, we need to focus a suitable child of the menu
|
37
|
+
// element since it is expected for the menu to close on click
|
38
|
+
const menu = this.#openButton?.closest('details') || this.#openButton?.closest('action-menu')
|
39
|
+
if (menu) {
|
40
|
+
focusIfNeeded(getFocusableChild(menu))
|
41
|
+
} else {
|
42
|
+
focusIfNeeded(this.#openButton)
|
43
|
+
}
|
44
|
+
this.#openButton = undefined
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
get #overlayBackdrop(): HTMLElement | null {
|
49
|
+
if (this.parentElement?.hasAttribute('data-modal-dialog-overlay')) {
|
50
|
+
return this.parentElement
|
51
|
+
}
|
52
|
+
|
53
|
+
return null
|
54
|
+
}
|
55
|
+
|
56
|
+
get showButtons(): NodeList {
|
57
|
+
// Dialogs may also be opened from any arbitrary button with a matching show-dialog-id data attribute
|
58
|
+
return document.querySelectorAll(`button[data-show-dialog-id='${this.id}']`)
|
59
|
+
}
|
60
|
+
|
61
|
+
connectedCallback(): void {
|
62
|
+
if (!this.hasAttribute('role')) this.setAttribute('role', 'dialog')
|
63
|
+
|
64
|
+
const {signal} = (this.#abortController = new AbortController())
|
65
|
+
|
66
|
+
this.ownerDocument.addEventListener(
|
67
|
+
'click',
|
68
|
+
event => {
|
69
|
+
const target = event.target as HTMLElement
|
70
|
+
const clickOutsideDialog = target.closest(this.tagName) !== this
|
71
|
+
const button = target?.closest('button')
|
72
|
+
// go over this logic:
|
73
|
+
if (!button) {
|
74
|
+
if (clickOutsideDialog) {
|
75
|
+
// This click is outside the dialog
|
76
|
+
this.close()
|
77
|
+
}
|
78
|
+
return
|
79
|
+
}
|
80
|
+
|
81
|
+
let dialogId = button.getAttribute('data-close-dialog-id')
|
82
|
+
if (dialogId === this.id) {
|
83
|
+
this.close()
|
84
|
+
}
|
85
|
+
|
86
|
+
dialogId = button.getAttribute('data-submit-dialog-id')
|
87
|
+
if (dialogId === this.id) {
|
88
|
+
this.close(true)
|
89
|
+
}
|
90
|
+
|
91
|
+
dialogId = button.getAttribute('data-show-dialog-id')
|
92
|
+
if (dialogId === this.id) {
|
93
|
+
event.stopPropagation()
|
94
|
+
this.#openButton = button
|
95
|
+
this.show()
|
96
|
+
}
|
97
|
+
},
|
98
|
+
{signal}
|
99
|
+
)
|
100
|
+
|
101
|
+
this.addEventListener('keydown', e => this.#keydown(e))
|
102
|
+
}
|
103
|
+
|
104
|
+
disconnectedCallback(): void {
|
105
|
+
this.#abortController?.abort()
|
106
|
+
}
|
107
|
+
|
108
|
+
show() {
|
109
|
+
this.open = true
|
110
|
+
}
|
111
|
+
|
112
|
+
close(closedNotCancelled = false) {
|
113
|
+
if (this.open === false) return
|
114
|
+
const eventType = closedNotCancelled ? 'close' : 'cancel'
|
115
|
+
const dialogEvent = new Event(eventType)
|
116
|
+
this.dispatchEvent(dialogEvent)
|
117
|
+
this.open = false
|
118
|
+
}
|
119
|
+
|
120
|
+
#keydown(event: Event) {
|
121
|
+
if (!(event instanceof KeyboardEvent)) return
|
122
|
+
if (event.isComposing) return
|
123
|
+
|
124
|
+
switch (event.key) {
|
125
|
+
case 'Escape':
|
126
|
+
if (this.open) {
|
127
|
+
this.close()
|
128
|
+
event.preventDefault()
|
129
|
+
event.stopPropagation()
|
130
|
+
}
|
131
|
+
break
|
132
|
+
}
|
133
|
+
}
|
134
|
+
}
|
135
|
+
|
136
|
+
declare global {
|
137
|
+
interface Window {
|
138
|
+
ModalDialogElement: typeof ModalDialogElement
|
139
|
+
}
|
140
|
+
interface HTMLElementTagNameMap {
|
141
|
+
'modal-dialog': ModalDialogElement
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
if (!window.customElements.get('modal-dialog')) {
|
146
|
+
window.ModalDialogElement = ModalDialogElement
|
147
|
+
window.customElements.define('modal-dialog', ModalDialogElement)
|
148
|
+
}
|
@@ -99,6 +99,8 @@ let ToggleSwitchElement = class ToggleSwitchElement extends HTMLElement {
|
|
99
99
|
}
|
100
100
|
body.append('value', this.isOn() ? '1' : '0');
|
101
101
|
try {
|
102
|
+
if (!this.src)
|
103
|
+
throw new Error('invalid src');
|
102
104
|
const response = await fetch(this.src, {
|
103
105
|
credentials: 'same-origin',
|
104
106
|
method: 'POST',
|
@@ -123,7 +123,8 @@ export class ToggleSwitchElement extends HTMLElement {
|
|
123
123
|
body.append('value', this.isOn() ? '1' : '0')
|
124
124
|
|
125
125
|
try {
|
126
|
-
|
126
|
+
if (!this.src) throw new Error('invalid src')
|
127
|
+
const response = await fetch(this.src, {
|
127
128
|
credentials: 'same-origin',
|
128
129
|
method: 'POST',
|
129
130
|
body
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<%= render Primer::ConditionalWrapper.new(condition: tooltip.present?, tag: :div, classes: "Button-withTooltip") do -%>
|
2
|
+
<%= render Primer::Beta::BaseButton.new(**@system_arguments) do -%>
|
3
|
+
<span class="<%= @align_content_classes %>">
|
4
|
+
<% if leading_visual %>
|
5
|
+
<span class="Button-visual Button-leadingVisual">
|
6
|
+
<%= leading_visual %>
|
7
|
+
</span>
|
8
|
+
<% end %>
|
9
|
+
<span class="Button-label"><%= trimmed_content %></span>
|
10
|
+
<% if trailing_visual %>
|
11
|
+
<span class="Button-visual Button-trailingVisual">
|
12
|
+
<%= trailing_visual %>
|
13
|
+
</span>
|
14
|
+
<% end %>
|
15
|
+
</span>
|
16
|
+
<% if trailing_action %>
|
17
|
+
<span class="Button-visual Button-trailingAction">
|
18
|
+
<%= trailing_action %>
|
19
|
+
</span>
|
20
|
+
<% end %>
|
21
|
+
<%= tooltip %>
|
22
|
+
<% end -%>
|
23
|
+
<% end -%>
|