@gitlab/ui
Version:
GitLab UI Components
21 lines (17 loc) • 6.49 kB
JavaScript
import examples from './examples';
var description = "# sprintf\n\n<!-- STORY -->\n\n## Basic\n\nThe `GlSprintf` component lets you do `sprintf`-style string interpolation with\nchild components. Each placeholder in the translated string, provided via the\n`message` prop, becomes a slot that you can use to insert any component in the\nrendered output.\n\n> NOTE: `gl-sprintf` does not translate the message for you; you must provide\n> it already translated. In the following examples, it is assumed that\n> a `gettext`-style `__` translation function is available in your Vue\n> templates.\n\n```html\n<div>\n <gl-sprintf :message=\"__('Written by %{author}')\">\n <template #author>\n <span>Author</span>\n </template>\n </gl-sprintf>\n</div>\n```\n\nThe example above renders to this HTML:\n\n```html\n<div>Written by <span>Author</span></div>\n```\n\n## Interpolated content\n\nSentences should not be split up into different messages, otherwise they may\nnot be translatable in certain languages. To help with this, `GlSprintf` is\nable to interpolate between placeholders suffixed with `Start` and `End`, and\npass whatever is between them to the scoped slot of the base name, via the\n`content` property.\n\nFor example:\n\n```html\n<div>\n <gl-sprintf :message=\"__('Learn more about %{linkStart}zones%{linkEnd}')\">\n <template #link=\"{ content }\">\n <gl-link\n href=\"https://cloud.google.com/compute/docs/regions-zones/regions-zones\"\n target=\"_blank\"\n >{{ content }}</gl-link>\n </template>\n </gl-sprintf>\n</div>\n```\n\nwill render as:\n\n```html\n<div>\n Learn more about\n <a\n href=\"https://cloud.google.com/compute/docs/regions-zones/regions-zones\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >zones</a>\n</div>\n```\n\nThe example above is formatted for readability, and so its whitespace\nis not technically correct, however, `GlSprintf` _will_ preserve whitespace\ncorrectly.\n\nNote that _any_ arbitrary Vue component(s) can be used within a scoped slot,\nand that the content passed to it can be used in any way at all; for instance,\nas regular text, or in component attributes or slots.\n\nHere's a more complex example, which `<gl-sprintf>` lets you do in a breeze:\n\n```html\n<div>\n <gl-sprintf :message=\"__('Written by %{authorStart}someone%{authorEnd}')\">\n <template #author=\"{ content }\">\n <my-vue-component v-gl-tooltip=\"content\" @event=\"handleEvent(content)\">\n {{ content }}\n </my-vue-component>\n <some-other-component />\n </template>\n </gl-sprintf>\n</div>\n```\n\nThis is not feasible in a JS-only solution, since arbitrary Vue components\ncannot easily be used. In addition, a JS-only solution is more likely to be\nprone to XSS attacks, as the Vue compiler isn't available to help protect\nagainst them.\n\n## Usage caveats\n\nWhile there are a lot of caveats here, you don't need to worry about reading\nthem _unless_ you find `GlSprintf` isn't rendering what you'd expect.\n\n- Since `GlSprintf` typically renders multiple elements, it can't be used as\n a component's root, it must be wrapped with at least one other root element,\n otherwise Vue will throw a `Multiple root nodes returned from render\n function` error.\n- If a slot for a given named interpolation _isn't_ provided, the interpolation\n will be rendered as-is, e.g., literally `Written by %{author}` if the\n `author` slot _isn't_ provided, or literally `%{linkStart}foo%{linkEnd}` if\n the `link` slot isn't provided.\n- Content between `Start` and `End` placeholders is effectively thrown away if\n the scoped slot of the correct name doesn't consume the `content` property in\n some way, though the slot's components should still be rendered.\n- If there's no named interpolation in the message for a provided named slot,\n the content of that slot is silently thrown away.\n- If only one of the `Start` or `End` placeholders is in the message, or they\n are in the wrong order, they are treated as plain slots. This allows you to\n use plain slots whose names end in `Start` or `End`, e.g., `backEnd`, or\n `fromStart`, without interpolating content into them.\n- Interpolation between `Start` and `End` placeholders is only done one level\n deep. This is intentional, so as to avoid building complex sprintf messages\n that would better be implemented in components. As an example,\n `${linkStart}test%{icon}%{linkEnd}`, if provided both the `link` and `icon`\n slots, would pass `test%{icon}` as a literal string as content to the `link`\n scoped slot.\n- To be successfully used in `GlSprintf`, slot names should:\n * start with a letter (`[A-Za-z]`)\n * only contain alpha-numeric characters (`[A-Za-z0-9]`), underscore (`_`) and\n dash (`-`),\n * should not end with underscore (`_`) or dash (`-`) So for example:\n `%{author}`, `%{author_name}`, `%{authorName}` or `%{author-name-100}` are\n all valid placeholders.\n\n## Internet Explorer 11\n\nThis component uses [`String.prototype.startsWith()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) and [`String.prototype.endsWith()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith) under the hood. Make sure those methods are polyfilled if you plan on using the component on IE11.\n\n> NOTE: These methods are already polyfilled in GitLab: [`app/assets/javascripts/commons/polyfills.js#L15-16`](https://gitlab.com/gitlab-org/gitlab/blob/dc60dee6ed6234dda9f032195577cd8fad9646d8/app/assets/javascripts/commons/polyfills.js#L15-16)\n";
var sprintf_documentation = {
followsDesignSystem: false,
description: description,
examples: examples,
propsInfo: {
message: {
additionalInfo: 'A translated string with named placeholders, e.g., "Written by %{author}".'
}
},
slots: [{
name: '* (arbitrary)',
description: 'Available slots are determined by the placeholders in the provided message prop. For example, a message of "Written by %{author}" has a slot called "author", and its content is used to replace "%{author}" in the rendered output. When two placeholders indicate a start and an end region in the message, e.g., "%{linkStart}foo%{linkEnd}", the common base name can be used as a scoped slot, where the content between the placeholders is passed via the `content` scoped slot prop.'
}]
};
export default sprintf_documentation;