@rancher/shell 3.0.9 → 3.0.11

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.
Files changed (104) hide show
  1. package/assets/styles/base/_color.scss +4 -0
  2. package/assets/styles/themes/_light.scss +6 -6
  3. package/assets/styles/themes/_modern.scss +14 -6
  4. package/assets/translations/en-us.yaml +9 -10
  5. package/chart/__tests__/rancher-backup-index.test.ts +248 -0
  6. package/chart/rancher-backup/index.vue +41 -2
  7. package/components/BrandImage.vue +6 -5
  8. package/components/ConsumptionGauge.vue +12 -4
  9. package/components/CopyToClipboard.vue +28 -0
  10. package/components/CopyToClipboardText.vue +4 -0
  11. package/components/CruResource.vue +1 -0
  12. package/components/DynamicContent/DynamicContentIcon.vue +3 -2
  13. package/components/ExplorerProjectsNamespaces.vue +1 -4
  14. package/components/GlobalRoleBindings.vue +1 -5
  15. package/components/LazyImage.vue +2 -1
  16. package/components/Resource/Detail/Card/Scaler.vue +4 -4
  17. package/components/ResourceDetail/index.vue +0 -21
  18. package/components/Tabbed/index.vue +6 -0
  19. package/components/__tests__/ConsumptionGauge.test.ts +31 -0
  20. package/components/__tests__/CruResource.test.ts +35 -1
  21. package/components/form/ProjectMemberEditor.vue +0 -10
  22. package/components/nav/TopLevelMenu.helper.ts +7 -79
  23. package/components/nav/__tests__/TopLevelMenu.helper.test.ts +2 -53
  24. package/composables/useIsNewDetailPageEnabled.test.ts +98 -0
  25. package/composables/useIsNewDetailPageEnabled.ts +12 -0
  26. package/config/private-label.js +2 -1
  27. package/config/product/apps.js +1 -0
  28. package/config/product/explorer.js +11 -1
  29. package/config/table-headers.js +0 -9
  30. package/config/types.js +0 -1
  31. package/core/__tests__/extension-manager-impl.test.js +187 -2
  32. package/core/extension-manager-impl.js +4 -2
  33. package/core/plugin-helpers.ts +31 -0
  34. package/detail/__tests__/node.test.ts +83 -0
  35. package/detail/management.cattle.io.oidcclient.vue +2 -1
  36. package/detail/node.vue +1 -0
  37. package/edit/auth/github-app-steps.vue +2 -0
  38. package/edit/auth/github-steps.vue +2 -0
  39. package/edit/catalog.cattle.io.clusterrepo.vue +17 -3
  40. package/edit/cloudcredential.vue +2 -1
  41. package/edit/management.cattle.io.user.vue +60 -35
  42. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +11 -6
  43. package/edit/provisioning.cattle.io.cluster/index.vue +5 -4
  44. package/edit/provisioning.cattle.io.cluster/shared.ts +4 -2
  45. package/edit/secret/generic.vue +1 -0
  46. package/edit/secret/index.vue +2 -1
  47. package/edit/service.vue +2 -14
  48. package/edit/token.vue +29 -68
  49. package/list/management.cattle.io.feature.vue +7 -1
  50. package/list/provisioning.cattle.io.cluster.vue +0 -49
  51. package/mixins/brand.js +2 -1
  52. package/models/catalog.cattle.io.clusterrepo.js +9 -0
  53. package/models/cluster.x-k8s.io.machinedeployment.js +8 -3
  54. package/models/management.cattle.io.authconfig.js +2 -1
  55. package/models/management.cattle.io.cluster.js +4 -3
  56. package/models/monitoring.coreos.com.receiver.js +11 -6
  57. package/models/provisioning.cattle.io.cluster.js +2 -2
  58. package/models/token.js +0 -4
  59. package/package.json +12 -12
  60. package/pages/account/index.vue +67 -96
  61. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +66 -9
  62. package/pages/c/_cluster/apps/charts/index.vue +3 -8
  63. package/pages/c/_cluster/apps/charts/install.vue +8 -9
  64. package/pages/c/_cluster/explorer/index.vue +2 -19
  65. package/pages/c/_cluster/istio/index.vue +4 -2
  66. package/pages/c/_cluster/longhorn/index.vue +2 -1
  67. package/pages/c/_cluster/monitoring/index.vue +2 -2
  68. package/pages/c/_cluster/neuvector/index.vue +2 -1
  69. package/pages/c/_cluster/settings/performance.vue +0 -5
  70. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -1
  71. package/pages/c/_cluster/uiplugins/index.vue +2 -1
  72. package/pkg/auto-import.js +41 -0
  73. package/plugins/dashboard-store/resource-class.js +2 -2
  74. package/plugins/steve/__tests__/steve-class.test.ts +1 -1
  75. package/plugins/steve/steve-class.js +3 -3
  76. package/plugins/steve/steve-pagination-utils.ts +2 -5
  77. package/plugins/steve/subscribe.js +29 -4
  78. package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.vue +7 -7
  79. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +5 -2
  80. package/rancher-components/RcButton/RcButton.vue +3 -3
  81. package/rancher-components/RcButtonSplit/RcButtonSplit.test.ts +253 -0
  82. package/rancher-components/RcButtonSplit/RcButtonSplit.vue +158 -0
  83. package/rancher-components/RcButtonSplit/index.ts +1 -0
  84. package/rancher-components/RcIcon/types.ts +2 -2
  85. package/rancher-components/RcSection/RcSection.test.ts +323 -0
  86. package/rancher-components/RcSection/RcSection.vue +252 -0
  87. package/rancher-components/RcSection/RcSectionActions.test.ts +212 -0
  88. package/rancher-components/RcSection/RcSectionActions.vue +85 -0
  89. package/rancher-components/RcSection/RcSectionBadges.test.ts +149 -0
  90. package/rancher-components/RcSection/RcSectionBadges.vue +29 -0
  91. package/rancher-components/RcSection/index.ts +12 -0
  92. package/rancher-components/RcSection/types.ts +86 -0
  93. package/scripts/test-plugins-build.sh +9 -8
  94. package/types/shell/index.d.ts +93 -108
  95. package/utils/__tests__/require-asset.test.ts +98 -0
  96. package/utils/async.ts +1 -5
  97. package/utils/brand.ts +3 -1
  98. package/utils/favicon.js +4 -3
  99. package/utils/require-asset.ts +95 -0
  100. package/utils/style.ts +17 -0
  101. package/utils/units.js +14 -5
  102. package/vue.config.js +4 -3
  103. package/components/HarvesterServiceAddOnConfig.vue +0 -207
  104. package/models/ext.cattle.io.token.js +0 -48
@@ -394,29 +394,12 @@ export default {
394
394
  },
395
395
 
396
396
  metricAggregations() {
397
- let checkNodes = this.nodes;
398
-
399
- // Special case local cluster
400
- if (this.currentCluster.isLocal) {
401
- const nodeNames = this.nodes.reduce((acc, n) => {
402
- acc[n.id] = n;
403
-
404
- return acc;
405
- }, {});
406
-
407
- checkNodes = this.mgmtNodes.filter((n) => {
408
- const nodeName = n.metadata?.labels?.['management.cattle.io/nodename'] || n.id;
409
-
410
- return !!nodeNames[nodeName];
411
- });
412
- }
413
-
414
- const someNonWorkerRoles = checkNodes.some((node) => node.hasARole && !node.isWorker);
415
397
  const metrics = this.nodeMetrics.filter((nodeMetrics) => {
416
398
  const node = this.nodes.find((nd) => nd.id === nodeMetrics.id);
417
399
 
418
- return node && (!someNonWorkerRoles || node.isWorker);
400
+ return node;
419
401
  });
402
+
420
403
  const initialAggregation = {
421
404
  cpu: 0,
422
405
  memory: 0
@@ -2,6 +2,8 @@
2
2
  import { mapGetters } from 'vuex';
3
3
  import { SERVICE } from '@shell/config/types';
4
4
  import Loading from '@shell/components/Loading';
5
+ import kialiSvg from '~shell/assets/images/vendor/kiali.svg';
6
+ import jaegerSvg from '~shell/assets/images/vendor/jaeger.svg';
5
7
  export default {
6
8
  components: { Loading },
7
9
 
@@ -23,7 +25,7 @@ export default {
23
25
 
24
26
  kialiLogo() {
25
27
  // @TODO move to theme css
26
- return require(`~shell/assets/images/vendor/kiali.svg`);
28
+ return kialiSvg;
27
29
  },
28
30
 
29
31
  kialiUrl() {
@@ -31,7 +33,7 @@ export default {
31
33
  },
32
34
 
33
35
  jaegerLogo() {
34
- return require(`~shell/assets/images/vendor/jaeger.svg`);
36
+ return jaegerSvg;
35
37
  },
36
38
 
37
39
  jaegerUrl() {
@@ -3,6 +3,7 @@ import { mapGetters } from 'vuex';
3
3
  import { SERVICE } from '@shell/config/types';
4
4
  import IconMessage from '@shell/components/IconMessage';
5
5
  import LazyImage from '@shell/components/LazyImage';
6
+ import longhornSvg from '~shell/assets/images/vendor/longhorn.svg';
6
7
  import Loading from '@shell/components/Loading';
7
8
 
8
9
  export default {
@@ -24,7 +25,7 @@ export default {
24
25
 
25
26
  data() {
26
27
  return {
27
- longhornImgSrc: require('~shell/assets/images/vendor/longhorn.svg'),
28
+ longhornImgSrc: longhornSvg,
28
29
  uiServices: null
29
30
  };
30
31
  },
@@ -9,6 +9,8 @@ import LazyImage from '@shell/components/LazyImage';
9
9
  import SimpleBox from '@shell/components/SimpleBox';
10
10
  import { canViewAlertManagerLink, canViewGrafanaLink, canViewPrometheusLink } from '@shell/utils/monitoring';
11
11
  import Loading from '@shell/components/Loading';
12
+ import grafanaSrc from '~shell/assets/images/vendor/grafana.svg';
13
+ import prometheusSrc from '~shell/assets/images/vendor/prometheus.svg';
12
14
 
13
15
  export default {
14
16
  components: {
@@ -23,8 +25,6 @@ export default {
23
25
  },
24
26
 
25
27
  data() {
26
- const grafanaSrc = require('~shell/assets/images/vendor/grafana.svg');
27
- const prometheusSrc = require('~shell/assets/images/vendor/prometheus.svg');
28
28
  const currentCluster = this.$store.getters['currentCluster'];
29
29
 
30
30
  return {
@@ -4,6 +4,7 @@ import { NEU_VECTOR_NAMESPACE } from '@shell/config/product/neuvector';
4
4
 
5
5
  import LazyImage from '@shell/components/LazyImage';
6
6
  import Loading from '@shell/components/Loading';
7
+ import neuvectorSvg from '~shell/assets/images/vendor/neuvector.svg';
7
8
 
8
9
  export default {
9
10
  components: { LazyImage, Loading },
@@ -11,7 +12,7 @@ export default {
11
12
  data() {
12
13
  return {
13
14
  externalLinks: [],
14
- neuvectorImgSrc: require('~shell/assets/images/vendor/neuvector.svg'),
15
+ neuvectorImgSrc: neuvectorSvg,
15
16
  };
16
17
  },
17
18
 
@@ -237,11 +237,6 @@ export default {
237
237
  {{ t('performance.serverPagination.label') }}
238
238
  </h2>
239
239
  <p>{{ t('performance.serverPagination.description') }}</p>
240
- <Banner
241
- color="warning"
242
- >
243
- <div v-clean-html="t(`performance.serverPagination.featureFlag`, { ffUrl }, true)" />
244
- </Banner>
245
240
  <Collapse
246
241
  :title="t('performance.serverPagination.applicable')"
247
242
  :open="steveCacheEnabled && ssPApplicableTypesOpen"
@@ -3,6 +3,7 @@ import { mapGetters } from 'vuex';
3
3
  import ChartReadme from '@shell/components/ChartReadme';
4
4
  import LazyImage from '@shell/components/LazyImage';
5
5
  import { MANAGEMENT } from '@shell/config/types';
6
+ import genericPluginSvg from '~shell/assets/images/generic-plugin.svg';
6
7
  import { SETTING } from '@shell/config/settings';
7
8
  import { useWatcherBasedSetupFocusTrapWithDestroyIncluded } from '@shell/composables/focusTrap';
8
9
  import { getPluginChartVersionLabel, getPluginChartVersion } from '@shell/utils/uiplugins';
@@ -36,7 +37,7 @@ export default {
36
37
  infoVersion: undefined,
37
38
  versionInfo: undefined,
38
39
  versionError: undefined,
39
- defaultIcon: require('~shell/assets/images/generic-plugin.svg'),
40
+ defaultIcon: genericPluginSvg,
40
41
  headerBannerSize: 0,
41
42
  isActive: false
42
43
  };
@@ -3,6 +3,7 @@ import { mapGetters } from 'vuex';
3
3
  import day from 'dayjs';
4
4
  import { mapPref, PLUGIN_DEVELOPER } from '@shell/store/prefs';
5
5
  import { sortBy } from '@shell/utils/sort';
6
+ import genericPluginSvg from '~shell/assets/images/generic-plugin.svg';
6
7
  import { allHash } from '@shell/utils/promise';
7
8
  import { CATALOG, UI_PLUGIN, MANAGEMENT, ZERO_TIME } from '@shell/config/types';
8
9
  import { SETTING } from '@shell/config/settings';
@@ -73,7 +74,7 @@ export default {
73
74
  menuTargetEvent: null,
74
75
  menuOpen: false,
75
76
  hasFeatureFlag: true,
76
- defaultIcon: require('~shell/assets/images/generic-plugin.svg'),
77
+ defaultIcon: genericPluginSvg,
77
78
  reloadRequired: false,
78
79
  rancherVersion: null
79
80
  };
@@ -11,6 +11,43 @@ function replaceAll(str, find, replace) {
11
11
  return str.split(find).join(replace);
12
12
  }
13
13
 
14
+ // Injected at the top of every generated importTypes() function.
15
+ // Ensures both $extension (newer Rancher) and $plugin (older Rancher) are available on
16
+ // Vue globalProperties, regardless of which one the host injected. This makes all
17
+ // extensions compatible across Rancher versions without any per-extension code changes.
18
+ const COMPAT_SHIM = ` if (typeof document !== 'undefined') {
19
+ var patchGlobalProps = function() {
20
+ var __vueApp = document.getElementById('app').__vue_app__;
21
+
22
+ if (!__vueApp) {
23
+ // no __vue_app__, vueApp.mount('#app') has not been called yet
24
+ return false;
25
+ }
26
+
27
+ if (__vueApp.config && __vueApp.config.globalProperties) {
28
+ var __gp = __vueApp.config.globalProperties;
29
+ if (!__gp.$extension && __gp.$plugin) { __gp.$extension = __gp.$plugin; }
30
+ else if (!__gp.$plugin && __gp.$extension) { __gp.$plugin = __gp.$extension; }
31
+ return true;
32
+ }
33
+
34
+ // Fallback to failure case
35
+ return false;
36
+ };
37
+
38
+ if (!patchGlobalProps()) {
39
+ // Could not patch, keep retrying until it works
40
+ var __retry = setInterval(function() {
41
+ if (patchGlobalProps()) {
42
+ clearInterval(__retry);
43
+ }
44
+ }, 100);
45
+
46
+ // Fallback: clear interval after 10 seconds just in case
47
+ setTimeout(function() { clearInterval(__retry); }, 10000);
48
+ }
49
+ }\n`;
50
+
14
51
  function registerFile(file, type, pkg, f) {
15
52
  const importType = (f === 'models') ? 'require' : 'import';
16
53
  const chunkName = (f === 'l10n') ? '' : `/* webpackChunkName: "${ f }" */`;
@@ -31,6 +68,8 @@ function register(file, pkg, f) {
31
68
  function generateTypeImport(pkg, dir) {
32
69
  let content = 'export function importTypes($extension) { \n';
33
70
 
71
+ content += COMPAT_SHIM;
72
+
34
73
  // Auto-import if the folder exists
35
74
  contextFolders.forEach((f) => {
36
75
  const filePath = path.join(dir, f);
@@ -79,6 +118,8 @@ function generateDynamicTypeImport(pkg, dir) {
79
118
  const template = fs.readFileSync(path.join(__dirname, 'import.js'), { encoding: 'utf8' });
80
119
  let content = 'export function importTypes($extension) { \n';
81
120
 
121
+ content += COMPAT_SHIM;
122
+
82
123
  // Auto-import if the folder exists
83
124
  contextFolders.forEach((f) => {
84
125
  if (fs.existsSync(path.join(dir, f))) {
@@ -1193,7 +1193,7 @@ export default class Resource {
1193
1193
  * Allow to handle the response of the save request
1194
1194
  * @param {*} res Full request response
1195
1195
  */
1196
- processSaveResponse(res) { }
1196
+ processSaveResponse(res, opt = {}) { }
1197
1197
 
1198
1198
  async _save(opt = { }) {
1199
1199
  const forNew = !this.id;
@@ -1280,7 +1280,7 @@ export default class Resource {
1280
1280
  const res = await this.$dispatch('request', { opt, type: this.type } );
1281
1281
 
1282
1282
  // Allow to process response independently from the related models
1283
- this.processSaveResponse(res);
1283
+ this.processSaveResponse(res, opt);
1284
1284
 
1285
1285
  // Steve sometimes returns Table responses instead of the resource you just saved.. ignore
1286
1286
  if ( res && res.kind !== 'Table') {
@@ -74,7 +74,7 @@ describe('class: Steve', () => {
74
74
 
75
75
  steve.processSaveResponse(response);
76
76
 
77
- expect(parentProcessSaveResponse).toHaveBeenCalledWith(response);
77
+ expect(parentProcessSaveResponse).toHaveBeenCalledWith(response, {});
78
78
  });
79
79
 
80
80
  describe('growl notifications', () => {
@@ -70,11 +70,11 @@ export default class SteveModel extends HybridModel {
70
70
  *
71
71
  * @param {*} res
72
72
  */
73
- processSaveResponse(res) {
74
- super.processSaveResponse(res);
73
+ processSaveResponse(res, opt = {}) {
74
+ super.processSaveResponse(res, opt);
75
75
 
76
76
  // Conditionally show the growl for autogenerated names
77
- if (res && res._status === 201 && res.metadata?.generateName && res.id) {
77
+ if (res && res._status === 201 && res.metadata?.generateName && res.id && !opt.suppressSuccessToast) {
78
78
  // Split to remove the namespace if present (default/generated-xxx)
79
79
  const nameOnly = res.id.split('/').pop();
80
80
 
@@ -15,8 +15,7 @@ import {
15
15
  INGRESS,
16
16
  WORKLOAD_TYPES,
17
17
  HPA,
18
- SECRET,
19
- EXT
18
+ SECRET
20
19
  } from '@shell/config/types';
21
20
  import { CAPI as CAPI_LAB_AND_ANO, CATTLE_PUBLIC_ENDPOINTS, STORAGE, UI_PROJECT_SECRET_COPY } from '@shell/config/labels-annotations';
22
21
  import { Schema } from '@shell/plugins/steve/schema';
@@ -767,9 +766,7 @@ export const PAGINATION_SETTINGS_STORE_DEFAULTS: PaginationSettingsStores = {
767
766
  { resource: CAPI.RANCHER_CLUSTER, context: ['side-bar'] },
768
767
  { resource: MANAGEMENT.CLUSTER, context: ['side-bar'] },
769
768
  { resource: CATALOG.APP, context: ['branding'] },
770
- SECRET,
771
- CAPI.MACHINE_SET,
772
- EXT.TOKEN
769
+ SECRET
773
770
  ],
774
771
  generic: false,
775
772
  }
@@ -131,11 +131,17 @@ const isWaitingForDestroy = (storeName, store) => {
131
131
  };
132
132
 
133
133
  const waitForSettingsSchema = (storeName, store) => {
134
- return waitFor(() => isWaitingForDestroy(storeName, store) || !!store.getters['management/byId'](SCHEMA, MANAGEMENT.SETTING));
134
+ return waitFor(
135
+ () => isWaitingForDestroy(storeName, store) || !!store.getters['management/byId'](SCHEMA, MANAGEMENT.SETTING),
136
+ 'management settings schema to be available'
137
+ );
135
138
  };
136
139
 
137
140
  const waitForSettings = (storeName, store) => {
138
- return waitFor(() => isWaitingForDestroy(storeName, store) || !!store.getters['management/byId'](MANAGEMENT.SETTING, SETTING.UI_PERFORMANCE));
141
+ return waitFor(
142
+ () => isWaitingForDestroy(storeName, store) || !!store.getters['management/byId'](MANAGEMENT.SETTING, SETTING.UI_PERFORMANCE),
143
+ 'UI performance settings to be available'
144
+ );
139
145
  };
140
146
 
141
147
  const isAdvancedWorker = (ctx) => {
@@ -195,8 +201,20 @@ export async function createWorker(store, ctx) {
195
201
  };
196
202
  }
197
203
 
198
- await waitForSettingsSchema(storeName, store);
199
- await waitForSettings(storeName, store);
204
+ try {
205
+ await waitForSettingsSchema(storeName, store);
206
+ await waitForSettings(storeName, store);
207
+ } catch (e) {
208
+ // Clean up the mock worker and abort so callers are not permanently blocked.
209
+ if (store.$workers[storeName]?.destroy) {
210
+ store.$workers[storeName].destroy();
211
+ } else {
212
+ delete store.$workers[storeName];
213
+ }
214
+
215
+ return;
216
+ }
217
+
200
218
  if (store.$workers[storeName].waitingForDestroy()) {
201
219
  store.$workers[storeName].destroy();
202
220
 
@@ -382,6 +400,13 @@ const sharedActions = {
382
400
  if (!this.$workers[getters.storeName]) {
383
401
  await createWorker(this, ctx);
384
402
  }
403
+
404
+ // createWorker cleans up and returns early when schema/settings are unavailable.
405
+ // Guard against calling postMessage on a non-existent worker.
406
+ if (!this.$workers[getters.storeName]) {
407
+ return;
408
+ }
409
+
385
410
  const options = { parseJSON: false };
386
411
  const csrf = rootGetters['cookies/get']({ key: CSRF, options });
387
412
 
@@ -11,27 +11,27 @@ const displayCount = computed(() => props.count < 1000 ? props.count : '999+');
11
11
  :class="{[props.type]: true, disabled: props.disabled}"
12
12
  data-testid="rc-counter-badge"
13
13
  >
14
- {{ displayCount }}
14
+ <span class="count">{{ displayCount }}</span>
15
15
  </div>
16
16
  </template>
17
17
 
18
18
  <style lang="scss" scoped>
19
19
  .rc-counter-badge {
20
+ box-sizing: border-box;
21
+ height: 21px;
22
+
20
23
  display: inline-flex;
21
- padding: 1px 8px;
24
+ padding: 2px 8px;
22
25
  align-items: center;
23
- gap: 8px;
24
26
 
25
27
  border-radius: 30px;
26
28
  border: 1px solid var(--rc-active-border);
27
29
 
28
- overflow: hidden;
29
- text-overflow: ellipsis;
30
30
  font-family: Lato;
31
- font-size: 13px;
31
+ font-size: 12px;
32
32
  font-style: normal;
33
33
  font-weight: 400;
34
- line-height: 22px;
34
+ line-height: 17px;
35
35
  color: var(--body-text);
36
36
 
37
37
  &.active {
@@ -20,17 +20,20 @@ const { backgroundColor, borderColor, textColor } = useStatusColors(status, 'out
20
20
 
21
21
  <style lang="scss" scoped>
22
22
  .rc-status-badge {
23
+ box-sizing: border-box;
24
+ height: 21px;
25
+
23
26
  display: inline-flex;
24
27
  align-items: center;
25
28
  justify-content: center;
26
- padding: 1px 7px;
29
+ padding: 2px 7px;
27
30
 
28
31
  border: 1px solid transparent;
29
32
  border-radius: 30px;
30
33
 
31
34
  font-family: Lato;
32
35
  font-size: 12px;
33
- line-height: 19px;
36
+ line-height: 17px;
34
37
 
35
38
  background-color: v-bind(backgroundColor);
36
39
  border-color: v-bind(borderColor);
@@ -253,7 +253,7 @@ button {
253
253
  &.btn-small {
254
254
  //:not(.btn-sm) is being used to make the style more specific to override global styles. We may want to get rid of those styles at some point.
255
255
  &, &:not(.btn-sm) {
256
- line-height: 15px;
256
+ line-height: 140%;
257
257
  font-size: 12px;
258
258
  min-height: 24px;
259
259
 
@@ -265,7 +265,7 @@ button {
265
265
  &.btn-medium {
266
266
  //:not(.btn-sm) is being used to make the style more specific to override global styles. We may want to get rid of those styles at some point.
267
267
  &, &:not(.btn-sm) {
268
- line-height: 18px;
268
+ line-height: 140%;
269
269
  font-size: 14px;
270
270
  min-height: 32px;
271
271
 
@@ -277,7 +277,7 @@ button {
277
277
  &.btn-large {
278
278
  // This is the default size brought by the global button styling
279
279
  &, &:not(.btn-sm) {
280
- line-height: 20px;
280
+ line-height: 140%;
281
281
  font-size: 16px;
282
282
  min-height: 40px;
283
283