primer_view_components 0.52.2 → 0.53.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 +14 -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/toggle_switch.css +1 -1
- data/app/components/primer/alpha/toggle_switch.css.map +1 -1
- data/app/components/primer/alpha/toggle_switch.pcss +8 -6
- data/app/components/primer/base_component.rb +1 -0
- data/app/components/primer/beta/blankslate.css +1 -1
- data/app/components/primer/beta/blankslate.css.map +1 -1
- data/app/components/primer/beta/blankslate.pcss +2 -53
- data/app/components/primer/component.rb +16 -0
- data/app/lib/primer/forms/dsl/input.rb +5 -1
- data/app/lib/primer/safe_href_helper.rb +36 -0
- data/lib/primer/view_components/version.rb +2 -2
- metadata +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
.ToggleSwitch,.ToggleSwitch.ToggleSwitch{display:inline-flex}.ToggleSwitch{align-items:center;gap:var(--controlStack-medium-gap-condensed)}.ToggleSwitch--checked .ToggleSwitch-statusOn{height:auto;visibility:visible}.ToggleSwitch--checked .ToggleSwitch-statusOff{height:0;visibility:hidden}.ToggleSwitch-track{position:relative;display:block;width:var(--base-size-64);height:var(--control-medium-size);padding:0;overflow:hidden;-webkit-text-decoration:none;text-decoration:none;cursor:pointer;-webkit-user-select:none;user-select:none;background-color:var(--controlTrack-bgColor-rest);border:var(--borderWidth-thin) solid var(--controlTrack-borderColor-rest);border-radius:var(--borderRadius-medium);transition-timing-function:cubic-bezier(.5,1,.89,1);transition-duration:80ms;transition-property:background-color,border-color;appearance:none}.ToggleSwitch-track:focus,.ToggleSwitch-track:focus-visible{outline-offset:1px}.ToggleSwitch-track:hover{background-color:var(--controlTrack-bgColor-hover)}.ToggleSwitch-track:active{background-color:var(--controlTrack-bgColor-active)}@media (pointer:coarse){:is(.ToggleSwitch-track:before){position:absolute;top:50%;left:50%;width:100%;height:100%;min-height:44px;content:"";transform:translateX(-50%) translateY(-50%)}}@media (prefers-reduced-motion){.ToggleSwitch-track,.ToggleSwitch-track *{transition:none}}.ToggleSwitch-track[aria-pressed=true][disabled]{color:var(--control-checked-fgColor-disabled);background-color:var(--controlTrack-bgColor-disabled);border-color:#0000}.ToggleSwitch-track[aria-pressed=true]{background-color:var(--control-checked-bgColor-rest);border-color:var(--borderColor-transparent)}.ToggleSwitch-track[aria-pressed=true]:not([disabled]):hover{background-color:var(--control-checked-bgColor-hover)}.ToggleSwitch-track[aria-pressed=true]:not([disabled]):active{background-color:var(--control-checked-bgColor-active)}.ToggleSwitch-track[aria-pressed=true] .ToggleSwitch-knob{background-color:var(--controlKnob-bgColor-checked);border-color:var(--controlKnob-borderColor-checked);transform:translateX(100%)}.ToggleSwitch-track[aria-pressed=true] .ToggleSwitch-lineIcon{transform:translateX(0)}.ToggleSwitch-track[aria-pressed=true] .ToggleSwitch-circleIcon{transform:translateX(100%)}.ToggleSwitch-track[disabled]{cursor:not-allowed;background-color:var(--controlTrack-bgColor-disabled);border-color:#0000;transition-property:none}.ToggleSwitch-track[disabled] .ToggleSwitch-knob{border-color:var(--borderColor-default)
|
|
1
|
+
.ToggleSwitch,.ToggleSwitch.ToggleSwitch{display:inline-flex}.ToggleSwitch{--toggleSwitch-knob-inset:var(--borderWidth-thin);--toggleSwitch-knob-offset:calc(var(--toggleSwitch-knob-inset)*2);align-items:center;gap:var(--controlStack-medium-gap-condensed)}.ToggleSwitch--checked .ToggleSwitch-statusOn{height:auto;visibility:visible}.ToggleSwitch--checked .ToggleSwitch-statusOff{height:0;visibility:hidden}.ToggleSwitch-track{position:relative;display:block;width:var(--base-size-64);height:var(--control-medium-size);padding:0;overflow:hidden;-webkit-text-decoration:none;text-decoration:none;cursor:pointer;-webkit-user-select:none;user-select:none;background-color:var(--controlTrack-bgColor-rest);border:var(--borderWidth-thin) solid var(--controlTrack-borderColor-rest);border-radius:var(--borderRadius-medium);transition-timing-function:cubic-bezier(.5,1,.89,1);transition-duration:80ms;transition-property:background-color,border-color;appearance:none}.ToggleSwitch-track:focus,.ToggleSwitch-track:focus-visible{outline-offset:1px}.ToggleSwitch-track:hover{background-color:var(--controlTrack-bgColor-hover)}.ToggleSwitch-track:active{background-color:var(--controlTrack-bgColor-active)}@media (pointer:coarse){:is(.ToggleSwitch-track:before){position:absolute;top:50%;left:50%;width:100%;height:100%;min-height:44px;content:"";transform:translateX(-50%) translateY(-50%)}}@media (prefers-reduced-motion){.ToggleSwitch-track,.ToggleSwitch-track *{transition:none}}.ToggleSwitch-track[aria-pressed=true][disabled]{color:var(--control-checked-fgColor-disabled);background-color:var(--controlTrack-bgColor-disabled);border-color:#0000}.ToggleSwitch-track[aria-pressed=true]{background-color:var(--control-checked-bgColor-rest);border-color:var(--borderColor-transparent)}.ToggleSwitch-track[aria-pressed=true]:not([disabled]):hover{background-color:var(--control-checked-bgColor-hover)}.ToggleSwitch-track[aria-pressed=true]:not([disabled]):active{background-color:var(--control-checked-bgColor-active)}.ToggleSwitch-track[aria-pressed=true] .ToggleSwitch-knob{background-color:var(--controlKnob-bgColor-checked);border-color:var(--controlKnob-borderColor-checked);transform:translateX(calc(100% - var(--toggleSwitch-knob-offset)))}.ToggleSwitch-track[aria-pressed=true] .ToggleSwitch-lineIcon{transform:translateX(0)}.ToggleSwitch-track[aria-pressed=true] .ToggleSwitch-circleIcon{transform:translateX(100%)}.ToggleSwitch-track[disabled]{cursor:not-allowed;background-color:var(--controlTrack-bgColor-disabled);border-color:#0000;transition-property:none}.ToggleSwitch-track[disabled] .ToggleSwitch-knob{border-color:var(--borderColor-default)}.ToggleSwitch-track[disabled] .ToggleSwitch-circleIcon,.ToggleSwitch-track[disabled] .ToggleSwitch-lineIcon{color:var(--controlTrack-fgColor-disabled)}.ToggleSwitch-icons{display:flex;align-items:center;width:100%;height:100%;overflow:hidden}.ToggleSwitch-lineIcon{color:var(--control-checked-fgColor-rest);transform:translateX(-100%)}.ToggleSwitch-circleIcon,.ToggleSwitch-lineIcon{line-height:0;transition-duration:80ms;transition-property:transform;flex:1 0 50%}.ToggleSwitch-circleIcon{color:var(--controlTrack-fgColor-rest);transform:translateX(0)}.ToggleSwitch-knob{position:absolute;inset-block:var(--toggleSwitch-knob-inset);inset-inline-start:var(--toggleSwitch-knob-inset);z-index:1;width:50%;background-color:var(--controlKnob-bgColor-rest);border:var(--borderWidth-thin) solid var(--controlKnob-borderColor-rest);border-radius:calc(var(--borderRadius-medium) - var(--toggleSwitch-knob-offset));transition-timing-function:cubic-bezier(.5,1,.89,1);transition-duration:80ms;transition-property:transform}@media (prefers-reduced-motion){.ToggleSwitch-knob{transition:none}}.ToggleSwitch-status{position:relative;font-size:var(--text-body-size-medium);line-height:var(--text-title-lineHeight-large);color:var(--fgColor-default);text-align:right}.ToggleSwitch-statusIcon{display:flex;width:var(--base-size-16);margin-top:.063rem}.ToggleSwitch--small .ToggleSwitch-status{font-size:var(--text-body-size-small)}.ToggleSwitch--small .ToggleSwitch-track{width:var(--base-size-48);height:var(--control-xsmall-size)}.ToggleSwitch--disabled .ToggleSwitch-status{color:var(--fgColor-muted)}.ToggleSwitch-statusOn{height:0;visibility:hidden}.ToggleSwitch-statusOff{height:auto;visibility:visible}.ToggleSwitch--statusAtEnd{flex-direction:row-reverse}.ToggleSwitch--statusAtEnd .ToggleSwitch-status{text-align:left}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["toggle_switch.pcss","<no source>"],"names":[],"mappings":"AAQA,yCAHE,
|
|
1
|
+
{"version":3,"sources":["toggle_switch.pcss","<no source>"],"names":[],"mappings":"AAQA,yCAHE,mBAUF,CAPA,cACE,iDAAkD,CAClD,iEAAoE,CAEpE,kBAAmB,CAEnB,4CACF,CAGE,8CACE,WAAY,CACZ,kBACF,CAEA,+CACE,QAAS,CACT,iBACF,CAGF,oBACE,iBAAkB,CAClB,aAAc,CACd,yBAA0B,CAC1B,iCAAkC,CAClC,SAAU,CACV,eAAgB,CAChB,4BAAqB,CAArB,oBAAqB,CACrB,cAAe,CACf,wBAAiB,CAAjB,gBAAiB,CACjB,iDAAkD,CAClD,yEAA0E,CAC1E,wCAAyC,CACzC,mDAAyD,CACzD,wBAAyB,CACzB,iDAAmD,CACnD,eA4BF,CA1BE,4DAEE,kBACF,CAEA,0BACE,kDACF,CAEA,2BACE,mDACF,CAEA,wBAEI,gCC9DN,kBAAA,QAAA,SAAA,WAAA,YAAA,gBAAA,WAAA,2CD8DgC,CAE9B,CAEA,gCAGE,0CACE,eACF,CACF,CAGF,iDACE,6CAA8C,CAC9C,qDAAsD,CACtD,kBACF,CAEA,uCACE,oDAAqD,CACrD,2CAyBF,CAtBI,6DACE,qDACF,CAEA,8DACE,sDACF,CAGF,0DACE,mDAAoD,CACpD,mDAAoD,CACpD,kEACF,CAEA,8DACE,uBACF,CAEA,gEACE,0BACF,CAGF,8BACE,kBAAmB,CACnB,qDAAsD,CACtD,kBAAyB,CACzB,wBAaF,CAXE,iDACE,uCACF,CAMA,4GACE,0CACF,CAGF,oBACE,YAAa,CACb,kBAAmB,CACnB,UAAW,CACX,WAAY,CACZ,eACF,CAEA,uBAGE,yCAA0C,CAG1C,2BAEF,CAEA,gDARE,aAAc,CAEd,wBAAyB,CACzB,6BAA8B,CAE9B,YAWF,CARA,yBAGE,sCAAuC,CAGvC,uBAEF,CAEA,mBACE,iBAAkB,CAClB,0CAA2C,CAC3C,iDAAkD,CAClD,SAAU,CACV,SAAU,CACV,gDAAiD,CACjD,wEAAyE,CAEzE,gFAAiF,CACjF,mDAAyD,CACzD,wBAAyB,CACzB,6BAKF,CAHE,gCAdF,mBAeI,eAEJ,CADE,CAGF,qBACE,iBAAkB,CAClB,sCAAuC,CACvC,8CAA+C,CAC/C,4BAA6B,CAC7B,gBACF,CAEA,yBACE,YAAa,CACb,yBAA0B,CAE1B,kBACF,CAGE,0CACE,qCACF,CAEA,yCACE,yBAA0B,CAC1B,iCACF,CAIA,6CACE,0BACF,CAGF,uBACE,QAAS,CACT,iBACF,CAEA,wBACE,WAAY,CACZ,kBACF,CAEA,2BACE,0BAKF,CAHE,gDACE,eACF","file":"toggle_switch.css","sourcesContent":["/* ToggleSwitch */\n\n/* Catalyst in dotcom applies a display: block to all web component elements. This\n** rule overrides it so the status label and toggle switch are laid out correctly. */\n.ToggleSwitch.ToggleSwitch {\n display: inline-flex;\n}\n\n.ToggleSwitch {\n --toggleSwitch-knob-inset: var(--borderWidth-thin);\n --toggleSwitch-knob-offset: calc(2 * var(--toggleSwitch-knob-inset));\n\n align-items: center;\n display: inline-flex;\n gap: var(--controlStack-medium-gap-condensed);\n}\n\n.ToggleSwitch--checked {\n & .ToggleSwitch-statusOn {\n height: auto;\n visibility: visible;\n }\n\n & .ToggleSwitch-statusOff {\n height: 0;\n visibility: hidden;\n }\n}\n\n.ToggleSwitch-track {\n position: relative;\n display: block;\n width: var(--base-size-64);\n height: var(--control-medium-size);\n padding: 0;\n overflow: hidden;\n text-decoration: none;\n cursor: pointer;\n user-select: none;\n background-color: var(--controlTrack-bgColor-rest);\n border: var(--borderWidth-thin) solid var(--controlTrack-borderColor-rest);\n border-radius: var(--borderRadius-medium);\n transition-timing-function: cubic-bezier(0.5, 1, 0.89, 1);\n transition-duration: 80ms;\n transition-property: background-color, border-color;\n appearance: none;\n\n &:focus,\n &:focus-visible {\n outline-offset: 1px;\n }\n\n &:hover {\n background-color: var(--controlTrack-bgColor-hover);\n }\n\n &:active {\n background-color: var(--controlTrack-bgColor-active);\n }\n\n @media (pointer: coarse) {\n &::before {\n @mixin minTouchTarget 44px;\n }\n }\n\n @media (prefers-reduced-motion) {\n transition: none;\n\n & * {\n transition: none;\n }\n }\n}\n\n.ToggleSwitch-track[aria-pressed='true'][disabled] {\n color: var(--control-checked-fgColor-disabled);\n background-color: var(--controlTrack-bgColor-disabled);\n border-color: transparent;\n}\n\n.ToggleSwitch-track[aria-pressed='true'] {\n background-color: var(--control-checked-bgColor-rest);\n border-color: var(--borderColor-transparent);\n\n &:not([disabled]) {\n &:hover {\n background-color: var(--control-checked-bgColor-hover);\n }\n\n &:active {\n background-color: var(--control-checked-bgColor-active);\n }\n }\n\n & .ToggleSwitch-knob {\n background-color: var(--controlKnob-bgColor-checked);\n border-color: var(--controlKnob-borderColor-checked);\n transform: translateX(calc(100% - var(--toggleSwitch-knob-offset)));\n }\n\n & .ToggleSwitch-lineIcon {\n transform: translateX(0%);\n }\n\n & .ToggleSwitch-circleIcon {\n transform: translateX(100%);\n }\n}\n\n.ToggleSwitch-track[disabled] {\n cursor: not-allowed;\n background-color: var(--controlTrack-bgColor-disabled);\n border-color: transparent;\n transition-property: none;\n\n & .ToggleSwitch-knob {\n border-color: var(--borderColor-default);\n }\n\n & .ToggleSwitch-lineIcon {\n color: var(--controlTrack-fgColor-disabled);\n }\n\n & .ToggleSwitch-circleIcon {\n color: var(--controlTrack-fgColor-disabled);\n }\n}\n\n.ToggleSwitch-icons {\n display: flex;\n align-items: center;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.ToggleSwitch-lineIcon {\n /* stylelint-disable-next-line primer/typography */\n line-height: 0;\n color: var(--control-checked-fgColor-rest);\n transition-duration: 80ms;\n transition-property: transform;\n transform: translateX(-100%);\n flex: 1 0 50%;\n}\n\n.ToggleSwitch-circleIcon {\n /* stylelint-disable-next-line primer/typography */\n line-height: 0;\n color: var(--controlTrack-fgColor-rest);\n transition-duration: 80ms;\n transition-property: transform;\n transform: translateX(0);\n flex: 1 0 50%;\n}\n\n.ToggleSwitch-knob {\n position: absolute;\n inset-block: var(--toggleSwitch-knob-inset);\n inset-inline-start: var(--toggleSwitch-knob-inset);\n z-index: 1;\n width: 50%;\n background-color: var(--controlKnob-bgColor-rest);\n border: var(--borderWidth-thin) solid var(--controlKnob-borderColor-rest);\n /* stylelint-disable-next-line primer/borders */\n border-radius: calc(var(--borderRadius-medium) - var(--toggleSwitch-knob-offset));\n transition-timing-function: cubic-bezier(0.5, 1, 0.89, 1);\n transition-duration: 80ms;\n transition-property: transform;\n\n @media (prefers-reduced-motion) {\n transition: none;\n }\n}\n\n.ToggleSwitch-status {\n position: relative;\n font-size: var(--text-body-size-medium);\n line-height: var(--text-title-lineHeight-large);\n color: var(--fgColor-default);\n text-align: right;\n}\n\n.ToggleSwitch-statusIcon {\n display: flex;\n width: var(--base-size-16);\n /* stylelint-disable-next-line primer/spacing */\n margin-top: 0.063rem;\n}\n\n.ToggleSwitch--small {\n & .ToggleSwitch-status {\n font-size: var(--text-body-size-small);\n }\n\n & .ToggleSwitch-track {\n width: var(--base-size-48);\n height: var(--control-xsmall-size);\n }\n}\n\n.ToggleSwitch--disabled {\n & .ToggleSwitch-status {\n color: var(--fgColor-muted);\n }\n}\n\n.ToggleSwitch-statusOn {\n height: 0;\n visibility: hidden;\n}\n\n.ToggleSwitch-statusOff {\n height: auto;\n visibility: visible;\n}\n\n.ToggleSwitch--statusAtEnd {\n flex-direction: row-reverse;\n\n & .ToggleSwitch-status {\n text-align: left;\n }\n}\n",null]}
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
.ToggleSwitch {
|
|
10
|
+
--toggleSwitch-knob-inset: var(--borderWidth-thin);
|
|
11
|
+
--toggleSwitch-knob-offset: calc(2 * var(--toggleSwitch-knob-inset));
|
|
12
|
+
|
|
10
13
|
align-items: center;
|
|
11
14
|
display: inline-flex;
|
|
12
15
|
gap: var(--controlStack-medium-gap-condensed);
|
|
@@ -93,7 +96,7 @@
|
|
|
93
96
|
& .ToggleSwitch-knob {
|
|
94
97
|
background-color: var(--controlKnob-bgColor-checked);
|
|
95
98
|
border-color: var(--controlKnob-borderColor-checked);
|
|
96
|
-
transform: translateX(100%);
|
|
99
|
+
transform: translateX(calc(100% - var(--toggleSwitch-knob-offset)));
|
|
97
100
|
}
|
|
98
101
|
|
|
99
102
|
& .ToggleSwitch-lineIcon {
|
|
@@ -113,7 +116,6 @@
|
|
|
113
116
|
|
|
114
117
|
& .ToggleSwitch-knob {
|
|
115
118
|
border-color: var(--borderColor-default);
|
|
116
|
-
box-shadow: none;
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
& .ToggleSwitch-lineIcon {
|
|
@@ -155,14 +157,14 @@
|
|
|
155
157
|
|
|
156
158
|
.ToggleSwitch-knob {
|
|
157
159
|
position: absolute;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
+
inset-block: var(--toggleSwitch-knob-inset);
|
|
161
|
+
inset-inline-start: var(--toggleSwitch-knob-inset);
|
|
160
162
|
z-index: 1;
|
|
161
163
|
width: 50%;
|
|
162
164
|
background-color: var(--controlKnob-bgColor-rest);
|
|
163
165
|
border: var(--borderWidth-thin) solid var(--controlKnob-borderColor-rest);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
+
/* stylelint-disable-next-line primer/borders */
|
|
167
|
+
border-radius: calc(var(--borderRadius-medium) - var(--toggleSwitch-knob-offset));
|
|
166
168
|
transition-timing-function: cubic-bezier(0.5, 1, 0.89, 1);
|
|
167
169
|
transition-duration: 80ms;
|
|
168
170
|
transition-property: transform;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.blankslate-container{container-type:inline-size;width:100%}.blankslate{--blankslate-outer-padding-block:var(--base-size-32);--blankslate-outer-padding-inline:var(--base-size-32);position:relative;padding:var(--blankslate-outer-padding-block) var(--blankslate-outer-padding-inline);text-align:center}.blankslate p{font-size:var(--text-body-size-
|
|
1
|
+
.blankslate-container{container-type:inline-size;width:100%}.blankslate{--blankslate-outer-padding-block:var(--base-size-32);--blankslate-outer-padding-inline:var(--base-size-32);position:relative;padding:var(--blankslate-outer-padding-block) var(--blankslate-outer-padding-inline);text-align:center}.blankslate p{color:var(--fgColor-muted)}.blankslate code,.blankslate p{font-size:var(--text-body-size-medium)}.blankslate code{padding:var(--base-size-2) var(--base-size-4) var(--base-size-4);background:var(--bgColor-default);border:var(--borderWidth-thin) solid var(--borderColor-muted);border-radius:var(--borderRadius-medium)}.blankslate img{width:56px;height:56px}.blankslate-icon{margin-right:var(--control-small-gap);margin-bottom:var(--stack-gap-condensed);margin-left:var(--control-small-gap);color:var(--fgColor-muted)}.blankslate-image{margin-bottom:var(--stack-gap-normal)}.blankslate-heading{margin-bottom:var(--base-size-4);font-size:var(--text-title-size-small);font-weight:var(--text-title-weight-medium);text-wrap:balance}.blankslate-description{text-wrap:balance}.blankslate-action{margin-top:var(--stack-gap-normal)}.blankslate-action:first-of-type{margin-top:var(--stack-gap-spacious)}.blankslate-action:last-of-type{margin-bottom:var(--stack-gap-condensed)}.blankslate-capped{border-radius:0 0 var(--borderRadius-medium) var(--borderRadius-medium)}.blankslate-spacious{--blankslate-outer-padding-block:var(--base-size-80);--blankslate-outer-padding-inline:var(--base-size-40)}.blankslate-narrow{max-width:485px;margin:0 auto}.blankslate-large img{width:80px;height:80px}.blankslate-large h3{margin:var(--stack-gap-normal) 0;font-size:24px}.blankslate-large p{font-size:var(--text-body-size-large)}.blankslate-clean-background{border:0}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["blankslate.pcss"],"names":[],"mappings":"AAEA,sBACE,0BAA2B,CAC3B,UACF,CAEA,YACE,oDAAqD,CACrD,qDAAsD,CAEtD,iBAAkB,CAElB,oFAAqF,CACrF,iBAsBF,CAnBE,
|
|
1
|
+
{"version":3,"sources":["blankslate.pcss"],"names":[],"mappings":"AAEA,sBACE,0BAA2B,CAC3B,UACF,CAEA,YACE,oDAAqD,CACrD,qDAAsD,CAEtD,iBAAkB,CAElB,oFAAqF,CACrF,iBAsBF,CAnBE,cAEE,0BACF,CAGA,+BALE,sCAWF,CANA,iBACE,gEAAiE,CAEjE,iCAAkC,CAClC,6DAA8D,CAC9D,wCACF,CAGA,gBACE,UAAW,CACX,WACF,CAGF,iBACE,qCAAsC,CACtC,wCAAyC,CACzC,oCAAqC,CACrC,0BACF,CAEA,kBACE,qCACF,CAEA,oBACE,gCAAiC,CACjC,sCAAuC,CACvC,2CAA4C,CAC5C,iBACF,CAEA,wBACE,iBACF,CAEA,mBACE,kCASF,CAPE,iCACE,oCACF,CAEA,gCACE,wCACF,CAGF,mBACE,uEACF,CAEA,qBACE,oDAAqD,CACrD,qDACF,CAEA,mBACE,eAAgB,CAChB,aACF,CAME,sBACE,UAAW,CACX,WACF,CAGA,qBACE,gCAAiC,CAIjC,cACF,CAGA,oBACE,qCACF,CAKF,6BACE,QACF","file":"blankslate.css","sourcesContent":["/* blankslate */\n\n.blankslate-container {\n container-type: inline-size;\n width: 100%;\n}\n\n.blankslate {\n --blankslate-outer-padding-block: var(--base-size-32);\n --blankslate-outer-padding-inline: var(--base-size-32);\n\n position: relative;\n /* stylelint-disable-next-line primer/spacing */\n padding: var(--blankslate-outer-padding-block) var(--blankslate-outer-padding-inline);\n text-align: center;\n\n /* stylelint-disable-next-line selector-max-type */\n & p {\n font-size: var(--text-body-size-medium);\n color: var(--fgColor-muted);\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & code {\n padding: var(--base-size-2) var(--base-size-4) var(--base-size-4);\n font-size: var(--text-body-size-medium);\n background: var(--bgColor-default);\n border: var(--borderWidth-thin) solid var(--borderColor-muted);\n border-radius: var(--borderRadius-medium);\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & img {\n width: 56px;\n height: 56px;\n }\n}\n\n.blankslate-icon {\n margin-right: var(--control-small-gap);\n margin-bottom: var(--stack-gap-condensed);\n margin-left: var(--control-small-gap);\n color: var(--fgColor-muted);\n}\n\n.blankslate-image {\n margin-bottom: var(--stack-gap-normal);\n}\n\n.blankslate-heading {\n margin-bottom: var(--base-size-4);\n font-size: var(--text-title-size-small);\n font-weight: var(--text-title-weight-medium);\n text-wrap: balance;\n}\n\n.blankslate-description {\n text-wrap: balance;\n}\n\n.blankslate-action {\n margin-top: var(--stack-gap-normal);\n\n &:first-of-type {\n margin-top: var(--stack-gap-spacious);\n }\n\n &:last-of-type {\n margin-bottom: var(--stack-gap-condensed);\n }\n}\n\n.blankslate-capped {\n border-radius: 0 0 var(--borderRadius-medium) var(--borderRadius-medium);\n}\n\n.blankslate-spacious {\n --blankslate-outer-padding-block: var(--base-size-80);\n --blankslate-outer-padding-inline: var(--base-size-40);\n}\n\n.blankslate-narrow {\n max-width: 485px;\n margin: 0 auto;\n}\n\n/* was .large-format\n** QUESTION: should we deprecate this? */\n.blankslate-large {\n /* stylelint-disable-next-line selector-max-type */\n & img {\n width: 80px;\n height: 80px;\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & h3 {\n margin: var(--stack-gap-normal) 0;\n\n /* font-size: $h3-size; // This doesn't actually make the text larger. Should this be $h2-size? */\n /* stylelint-disable-next-line primer/typography */\n font-size: 24px;\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & p {\n font-size: var(--text-body-size-large);\n }\n}\n\n/* was .clean-background\n** TO DO: deprecate this and use utility instead */\n.blankslate-clean-background {\n border: 0;\n}\n"]}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
/* stylelint-disable-next-line selector-max-type */
|
|
18
18
|
& p {
|
|
19
|
-
font-size: var(--text-body-size-
|
|
19
|
+
font-size: var(--text-body-size-medium);
|
|
20
20
|
color: var(--fgColor-muted);
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -37,23 +37,19 @@
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.blankslate-icon {
|
|
40
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
41
40
|
margin-right: var(--control-small-gap);
|
|
42
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
43
41
|
margin-bottom: var(--stack-gap-condensed);
|
|
44
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
45
42
|
margin-left: var(--control-small-gap);
|
|
46
43
|
color: var(--fgColor-muted);
|
|
47
44
|
}
|
|
48
45
|
|
|
49
46
|
.blankslate-image {
|
|
50
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
51
47
|
margin-bottom: var(--stack-gap-normal);
|
|
52
48
|
}
|
|
53
49
|
|
|
54
50
|
.blankslate-heading {
|
|
55
51
|
margin-bottom: var(--base-size-4);
|
|
56
|
-
font-size: var(--text-title-size-
|
|
52
|
+
font-size: var(--text-title-size-small);
|
|
57
53
|
font-weight: var(--text-title-weight-medium);
|
|
58
54
|
text-wrap: balance;
|
|
59
55
|
}
|
|
@@ -63,16 +59,13 @@
|
|
|
63
59
|
}
|
|
64
60
|
|
|
65
61
|
.blankslate-action {
|
|
66
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
67
62
|
margin-top: var(--stack-gap-normal);
|
|
68
63
|
|
|
69
64
|
&:first-of-type {
|
|
70
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
71
65
|
margin-top: var(--stack-gap-spacious);
|
|
72
66
|
}
|
|
73
67
|
|
|
74
68
|
&:last-of-type {
|
|
75
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
76
69
|
margin-bottom: var(--stack-gap-condensed);
|
|
77
70
|
}
|
|
78
71
|
}
|
|
@@ -102,7 +95,6 @@
|
|
|
102
95
|
|
|
103
96
|
/* stylelint-disable-next-line selector-max-type */
|
|
104
97
|
& h3 {
|
|
105
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
106
98
|
margin: var(--stack-gap-normal) 0;
|
|
107
99
|
|
|
108
100
|
/* font-size: $h3-size; // This doesn't actually make the text larger. Should this be $h2-size? */
|
|
@@ -121,46 +113,3 @@
|
|
|
121
113
|
.blankslate-clean-background {
|
|
122
114
|
border: 0;
|
|
123
115
|
}
|
|
124
|
-
|
|
125
|
-
/* At the time these styles were written,
|
|
126
|
-
`34rem` was our "small" breakpoint width */
|
|
127
|
-
@container (max-width: 34rem) {
|
|
128
|
-
.blankslate {
|
|
129
|
-
--blankslate-outer-padding-block: var(--base-size-20);
|
|
130
|
-
--blankslate-outer-padding-inline: var(--base-size-20);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.blankslate-spacious {
|
|
134
|
-
--blankslate-outer-padding-block: var(--base-size-44);
|
|
135
|
-
--blankslate-outer-padding-inline: var(--base-size-28);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.blankslate-icon {
|
|
139
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
140
|
-
margin-bottom: var(--stack-gap-condensed);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.blankslate-heading {
|
|
144
|
-
font-size: var(--text-title-size-small);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/* stylelint-disable-next-line selector-max-type */
|
|
148
|
-
.blankslate p {
|
|
149
|
-
font-size: var(--text-body-size-medium);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.blankslate-action {
|
|
153
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
154
|
-
margin-top: var(--stack-gap-condensed);
|
|
155
|
-
|
|
156
|
-
&:first-of-type {
|
|
157
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
158
|
-
margin-top: var(--stack-gap-normal);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
&:last-of-type {
|
|
162
|
-
/* stylelint-disable-next-line primer/spacing */
|
|
163
|
-
margin-bottom: calc(var(--stack-gap-condensed) / 2);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
@@ -22,6 +22,7 @@ module Primer
|
|
|
22
22
|
include AttributesHelper
|
|
23
23
|
include ClassNameHelper
|
|
24
24
|
include FetchOrFallbackHelper
|
|
25
|
+
include SafeHrefHelper
|
|
25
26
|
include TestSelectorHelper
|
|
26
27
|
include JoinStyleArgumentsHelper
|
|
27
28
|
include ViewHelper
|
|
@@ -137,6 +138,21 @@ module Primer
|
|
|
137
138
|
deny_single_argument(:tag, "This component has a fixed tag.", **arguments)
|
|
138
139
|
end
|
|
139
140
|
|
|
141
|
+
# Removes `href` values that point at disallowed URI schemes (`javascript:`,
|
|
142
|
+
# `vbscript:`). Raises in non-production environments so the offending call
|
|
143
|
+
# site gets fixed; in production we silently drop the attribute so the link
|
|
144
|
+
# is rendered inert rather than crashing the page.
|
|
145
|
+
def sanitize_href!(arguments)
|
|
146
|
+
return unless arguments.key?(:href)
|
|
147
|
+
return unless Primer::SafeHrefHelper.unsafe_href?(arguments[:href])
|
|
148
|
+
|
|
149
|
+
if should_raise_error?
|
|
150
|
+
raise ArgumentError, "Rejected dangerous URI scheme in `href`: #{arguments[:href].inspect}"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
arguments[:href] = nil
|
|
154
|
+
end
|
|
155
|
+
|
|
140
156
|
def should_raise_error?
|
|
141
157
|
!Rails.env.production? && raise_on_invalid_options? && !ENV["PRIMER_WARNINGS_DISABLED"]
|
|
142
158
|
end
|
|
@@ -61,7 +61,6 @@ module Primer
|
|
|
61
61
|
@input_arguments = system_arguments
|
|
62
62
|
@input_arguments.delete(:id) unless @input_arguments[:id].present?
|
|
63
63
|
@label_arguments = @input_arguments.delete(:label_arguments) || {}
|
|
64
|
-
@label_arguments[:for] = id if id.present?
|
|
65
64
|
|
|
66
65
|
@label_arguments[:class] = class_names(
|
|
67
66
|
@label_arguments[:class],
|
|
@@ -105,6 +104,11 @@ module Primer
|
|
|
105
104
|
end
|
|
106
105
|
# rubocop:enable Style/IfUnlessModifier
|
|
107
106
|
|
|
107
|
+
# Only set `for` when the id is known. Otherwise leave it unset so
|
|
108
|
+
# Rails generates the scoped id for both label and input; passing
|
|
109
|
+
# `for: nil` would suppress that and drop the association.
|
|
110
|
+
@label_arguments[:for] = @input_arguments[:id] if @input_arguments[:id].present?
|
|
111
|
+
|
|
108
112
|
# Whether or not to wrap the component in a FormControl, which renders a
|
|
109
113
|
# label above and validation message beneath the input.
|
|
110
114
|
@form_control = @input_arguments.delete(:form_control) { true }
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Primer::SafeHrefHelper
|
|
4
|
+
#
|
|
5
|
+
# Detects unsafe URI schemes (e.g. `javascript:`) in `href` values so they can
|
|
6
|
+
# be neutralized before being rendered into HTML attributes. Without this check,
|
|
7
|
+
# a caller that forwards untrusted input into a component's `href:` argument can
|
|
8
|
+
# trigger XSS when the user clicks the rendered anchor.
|
|
9
|
+
module Primer
|
|
10
|
+
# :nodoc:
|
|
11
|
+
module SafeHrefHelper
|
|
12
|
+
# URI schemes that can execute script in the browser and are never valid
|
|
13
|
+
# destinations for a Primer-rendered link.
|
|
14
|
+
DISALLOWED_HREF_SCHEMES = %w[javascript vbscript].freeze
|
|
15
|
+
|
|
16
|
+
# Returns true when `href` starts with a disallowed URI scheme.
|
|
17
|
+
#
|
|
18
|
+
# Mirrors browser URL parsing by stripping ASCII whitespace and control
|
|
19
|
+
# characters (including tab/CR/LF) before extracting the scheme. This
|
|
20
|
+
# prevents bypasses such as `j\tavascript:...`, ` JaVaScRiPt:...`, or a
|
|
21
|
+
# leading null byte, all of which browsers happily execute.
|
|
22
|
+
def self.unsafe_href?(href)
|
|
23
|
+
return false if href.nil?
|
|
24
|
+
|
|
25
|
+
normalized = href.to_s.gsub(/[\u0000-\u0020]/, "")
|
|
26
|
+
scheme = normalized[/\A([a-z][a-z0-9+\-.]*):/i, 1]
|
|
27
|
+
return false unless scheme
|
|
28
|
+
|
|
29
|
+
DISALLOWED_HREF_SCHEMES.include?(scheme.downcase)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def unsafe_href?(href)
|
|
33
|
+
SafeHrefHelper.unsafe_href?(href)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: primer_view_components
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.53.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GitHub Open Source
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actionview
|
|
@@ -723,6 +723,7 @@ files:
|
|
|
723
723
|
- app/lib/primer/forms/validation_message.rb
|
|
724
724
|
- app/lib/primer/join_style_arguments_helper.rb
|
|
725
725
|
- app/lib/primer/octicon/cache.rb
|
|
726
|
+
- app/lib/primer/safe_href_helper.rb
|
|
726
727
|
- app/lib/primer/status/dsl.rb
|
|
727
728
|
- app/lib/primer/tab_nav_helper.rb
|
|
728
729
|
- app/lib/primer/tabbed_component_helper.rb
|