@gitlab/ui 66.2.0 → 66.3.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [66.3.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v66.2.0...v66.3.0) (2023-08-30)
2
+
3
+
4
+ ### Features
5
+
6
+ * accept generic translations at configuration time ([c3e04c7](https://gitlab.com/gitlab-org/gitlab-ui/commit/c3e04c7b72db211bcf3b34c9c47dc42214d1b3db))
7
+
1
8
  # [66.2.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v66.1.0...v66.2.0) (2023-08-30)
2
9
 
3
10
 
package/dist/charts.js CHANGED
@@ -1,4 +1,3 @@
1
- import setConfigs from './config';
2
1
  export { default as GlChart } from './components/charts/chart/chart';
3
2
  export { default as GlAreaChart } from './components/charts/area/area';
4
3
  export { default as GlBarChart } from './components/charts/bar/bar';
@@ -13,6 +12,3 @@ export { default as GlStackedColumnChart } from './components/charts/stacked_col
13
12
  export { default as GlDiscreteScatterChart } from './components/charts/discrete_scatter/discrete_scatter';
14
13
  export { default as GlSingleStat } from './components/charts/single_stat/single_stat';
15
14
  export { default as GlSparklineChart } from './components/charts/sparkline/sparkline';
16
-
17
- // Add config files
18
- setConfigs();
@@ -2,6 +2,7 @@ import GlClearIconButton from '../../shared_components/clear_icon_button/clear_i
2
2
  import GlFormInput from '../form/form_input/form_input';
3
3
  import GlIcon from '../icon/icon';
4
4
  import GlLoadingIcon from '../loading_icon/loading_icon';
5
+ import { translate } from '../../../utils/i18n';
5
6
  import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
6
7
 
7
8
  var script = {
@@ -34,7 +35,7 @@ var script = {
34
35
  clearButtonTitle: {
35
36
  type: String,
36
37
  required: false,
37
- default: 'Clear'
38
+ default: () => translate('GlSearchBoxByType.clearButtonTitle', 'Clear')
38
39
  },
39
40
  /**
40
41
  * If provided and true, disables the input and controls
@@ -65,7 +66,7 @@ var script = {
65
66
  inputAttributes() {
66
67
  const attributes = {
67
68
  type: 'search',
68
- placeholder: 'Search',
69
+ placeholder: translate('GlSearchBoxByType.input.placeholder', 'Search'),
69
70
  ...this.$attrs
70
71
  };
71
72
  if (!attributes['aria-label']) {
@@ -1,5 +1,6 @@
1
1
  import { GlTooltipDirective } from '../../../directives/tooltip';
2
2
  import GlButton from '../../base/button/button';
3
+ import { translate } from '../../../utils/i18n';
3
4
  import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
4
5
 
5
6
  var script = {
@@ -14,7 +15,7 @@ var script = {
14
15
  title: {
15
16
  type: String,
16
17
  required: false,
17
- default: 'Clear'
18
+ default: () => translate('ClearIconButton.title', 'Clear')
18
19
  },
19
20
  tooltipContainer: {
20
21
  required: false,
package/dist/config.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { BVConfigPlugin } from 'bootstrap-vue/esm/index.js';
2
2
  import Vue from 'vue';
3
+ import translationKeys from '../translations.json';
3
4
  import { tooltipDelay } from './utils/constants';
4
5
 
5
6
  const bFormTextGlobalConfig = {
@@ -28,11 +29,51 @@ try {
28
29
  } catch (e) {
29
30
  // localStorage doesn't exist (or the value is not properly formatted)
30
31
  }
31
- const setConfigs = () => {
32
+ const i18n = translationKeys;
33
+ let configured = false;
34
+
35
+ /**
36
+ * Set GitLab UI configuration.
37
+ *
38
+ * @typedef {object} GitLabUIConfiguration
39
+ * @template TValue=string
40
+ * @property {undefined | Object} translations Generic translations for component labels to fall back to.
41
+ * @property {boolean} disableTranslations Whether translation capabilities should be disabled. Suppresses the warning about missing translations.
42
+ */
43
+ const setConfigs = function () {
44
+ let {
45
+ translations
46
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
47
+ if (configured) {
48
+ if (process.env.NODE_ENV === 'development') {
49
+ throw new Error('GitLab UI can only be configured once!');
50
+ }
51
+ return;
52
+ }
53
+ configured = true;
32
54
  Vue.use(BVConfigPlugin, {
33
55
  BFormText: bFormTextGlobalConfig,
34
56
  BTooltip: tooltipGlobalConfig
35
57
  });
58
+ if (typeof translations === 'object') {
59
+ if (process.env.NODE_ENV === 'development') {
60
+ const undefinedTranslationKeys = Object.keys(i18n).reduce((acc, current) => {
61
+ if (!(current in translations)) {
62
+ acc.push(current);
63
+ }
64
+ return acc;
65
+ }, []);
66
+ if (undefinedTranslationKeys.length) {
67
+ /* eslint-disable no-console */
68
+ console.warn('[@gitlab/ui] The following translations have not been given, so will fall back to their default US English strings:');
69
+ console.table(undefinedTranslationKeys);
70
+ /* eslint-enable no-console */
71
+ }
72
+ }
73
+
74
+ Object.assign(i18n, translations);
75
+ }
36
76
  };
37
77
 
38
78
  export default setConfigs;
79
+ export { i18n };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 30 Aug 2023 05:58:01 GMT
3
+ * Generated on Wed, 30 Aug 2023 06:58:09 GMT
4
4
  */
5
5
 
6
6
  :root {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 30 Aug 2023 05:58:01 GMT
3
+ * Generated on Wed, 30 Aug 2023 06:58:09 GMT
4
4
  */
5
5
 
6
6
  :root {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 30 Aug 2023 05:58:01 GMT
3
+ * Generated on Wed, 30 Aug 2023 06:58:09 GMT
4
4
  */
5
5
 
6
6
  export const BLACK = "#fff";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 30 Aug 2023 05:58:01 GMT
3
+ * Generated on Wed, 30 Aug 2023 06:58:09 GMT
4
4
  */
5
5
 
6
6
  export const BLACK = "#000";
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Wed, 30 Aug 2023 05:58:01 GMT
3
+ // Generated on Wed, 30 Aug 2023 06:58:09 GMT
4
4
 
5
5
  $red-950: #fff4f3;
6
6
  $red-900: #fcf1ef;
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Wed, 30 Aug 2023 05:58:01 GMT
3
+ // Generated on Wed, 30 Aug 2023 06:58:09 GMT
4
4
 
5
5
  $brand-gray-05: #2b2838 !default;
6
6
  $brand-gray-04: #45424d !default;
@@ -0,0 +1,15 @@
1
+ import { i18n } from '../config';
2
+
3
+ /**
4
+ * Mark a label as translatable.
5
+ *
6
+ * @param {string} key Translation key to be leveraged by the consumer to provide a generic translation at configuration time.
7
+ * @param {string} defaultValue A fallback value to be relied on if the consumer doesn't have translation capabilities.
8
+ * @returns {string} The translated label.
9
+ */
10
+ const translate = (key, defaultValue) => {
11
+ var _i18n$key;
12
+ return (_i18n$key = i18n[key]) !== null && _i18n$key !== void 0 ? _i18n$key : defaultValue;
13
+ };
14
+
15
+ export { translate };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "66.2.0",
3
+ "version": "66.3.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -17,7 +17,8 @@
17
17
  "files": [
18
18
  "src",
19
19
  "dist",
20
- "scss_to_js"
20
+ "scss_to_js",
21
+ "translations.json"
21
22
  ],
22
23
  "scripts": {
23
24
  "build": "NODE_ENV=production rollup -c",
@@ -60,7 +61,8 @@
60
61
  "markdownlint:fix": "yarn markdownlint --fix",
61
62
  "lint": "run-p prettier eslint stylelint markdownlint",
62
63
  "lint:fix": "run-s prettier:fix eslint:fix stylelint:fix markdownlint:fix",
63
- "generate:component": "plop"
64
+ "generate:component": "plop",
65
+ "translations:collect": "make translations.json"
64
66
  },
65
67
  "dependencies": {
66
68
  "@floating-ui/dom": "1.2.9",
@@ -126,7 +128,7 @@
126
128
  "eslint-import-resolver-jest": "3.0.2",
127
129
  "eslint-plugin-cypress": "2.14.0",
128
130
  "eslint-plugin-storybook": "0.6.13",
129
- "glob": "^7.2.0",
131
+ "glob": "10.3.3",
130
132
  "identity-obj-proxy": "^3.0.0",
131
133
  "inquirer-select-directory": "^1.2.0",
132
134
  "jest": "^29.6.4",
package/src/charts.js CHANGED
@@ -1,8 +1,3 @@
1
- // Add config files
2
- import setConfigs from './config';
3
-
4
- setConfigs();
5
-
6
1
  export { default as GlChart } from './components/charts/chart/chart.vue';
7
2
  export { default as GlAreaChart } from './components/charts/area/area.vue';
8
3
  export { default as GlBarChart } from './components/charts/bar/bar.vue';
@@ -3,6 +3,7 @@ import GlClearIconButton from '../../shared_components/clear_icon_button/clear_i
3
3
  import GlFormInput from '../form/form_input/form_input.vue';
4
4
  import GlIcon from '../icon/icon.vue';
5
5
  import GlLoadingIcon from '../loading_icon/loading_icon.vue';
6
+ import { translate } from '../../../utils/i18n';
6
7
 
7
8
  export default {
8
9
  name: 'GlSearchboxByType',
@@ -34,7 +35,7 @@ export default {
34
35
  clearButtonTitle: {
35
36
  type: String,
36
37
  required: false,
37
- default: 'Clear',
38
+ default: () => translate('GlSearchBoxByType.clearButtonTitle', 'Clear'),
38
39
  },
39
40
  /**
40
41
  * If provided and true, disables the input and controls
@@ -66,7 +67,7 @@ export default {
66
67
  inputAttributes() {
67
68
  const attributes = {
68
69
  type: 'search',
69
- placeholder: 'Search',
70
+ placeholder: translate('GlSearchBoxByType.input.placeholder', 'Search'),
70
71
  ...this.$attrs,
71
72
  };
72
73
 
@@ -1,6 +1,7 @@
1
1
  <script>
2
2
  import { GlTooltipDirective } from '../../../directives/tooltip';
3
3
  import GlButton from '../../base/button/button.vue';
4
+ import { translate } from '../../../utils/i18n';
4
5
 
5
6
  export default {
6
7
  name: 'ClearIconButton',
@@ -14,7 +15,7 @@ export default {
14
15
  title: {
15
16
  type: String,
16
17
  required: false,
17
- default: 'Clear',
18
+ default: () => translate('ClearIconButton.title', 'Clear'),
18
19
  },
19
20
  tooltipContainer: {
20
21
  required: false,
package/src/config.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { BVConfigPlugin } from 'bootstrap-vue';
2
2
  import Vue from 'vue';
3
+ import translationKeys from '../translations.json';
3
4
  import { tooltipDelay } from './utils/constants';
4
5
 
5
6
  const bFormTextGlobalConfig = {
@@ -31,11 +32,53 @@ try {
31
32
  // localStorage doesn't exist (or the value is not properly formatted)
32
33
  }
33
34
 
34
- const setConfigs = () => {
35
+ export const i18n = translationKeys;
36
+
37
+ let configured = false;
38
+
39
+ /**
40
+ * Set GitLab UI configuration.
41
+ *
42
+ * @typedef {object} GitLabUIConfiguration
43
+ * @template TValue=string
44
+ * @property {undefined | Object} translations Generic translations for component labels to fall back to.
45
+ * @property {boolean} disableTranslations Whether translation capabilities should be disabled. Suppresses the warning about missing translations.
46
+ */
47
+ const setConfigs = ({ translations } = {}) => {
48
+ if (configured) {
49
+ if (process.env.NODE_ENV === 'development') {
50
+ throw new Error('GitLab UI can only be configured once!');
51
+ }
52
+
53
+ return;
54
+ }
55
+ configured = true;
56
+
35
57
  Vue.use(BVConfigPlugin, {
36
58
  BFormText: bFormTextGlobalConfig,
37
59
  BTooltip: tooltipGlobalConfig,
38
60
  });
61
+
62
+ if (typeof translations === 'object') {
63
+ if (process.env.NODE_ENV === 'development') {
64
+ const undefinedTranslationKeys = Object.keys(i18n).reduce((acc, current) => {
65
+ if (!(current in translations)) {
66
+ acc.push(current);
67
+ }
68
+ return acc;
69
+ }, []);
70
+ if (undefinedTranslationKeys.length) {
71
+ /* eslint-disable no-console */
72
+ console.warn(
73
+ '[@gitlab/ui] The following translations have not been given, so will fall back to their default US English strings:'
74
+ );
75
+ console.table(undefinedTranslationKeys);
76
+ /* eslint-enable no-console */
77
+ }
78
+ }
79
+
80
+ Object.assign(i18n, translations);
81
+ }
39
82
  };
40
83
 
41
84
  export default setConfigs;
@@ -0,0 +1,10 @@
1
+ import { i18n } from '../config';
2
+
3
+ /**
4
+ * Mark a label as translatable.
5
+ *
6
+ * @param {string} key Translation key to be leveraged by the consumer to provide a generic translation at configuration time.
7
+ * @param {string} defaultValue A fallback value to be relied on if the consumer doesn't have translation capabilities.
8
+ * @returns {string} The translated label.
9
+ */
10
+ export const translate = (key, defaultValue) => i18n[key] ?? defaultValue;
@@ -0,0 +1,5 @@
1
+ {
2
+ "ClearIconButton.title": "Clear",
3
+ "GlSearchBoxByType.clearButtonTitle": "Clear",
4
+ "GlSearchBoxByType.input.placeholder": "Search"
5
+ }