UNPKG

@gitlab/ui

Version:
9 lines (6 loc) 8.74 kB
var description = "## Overview\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 components or\nmarkup in the rendered 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## Displaying messages with text between placeholders (e.g., links, buttons)\n\nSentences should not be split up into different messages, otherwise they may\nnot be translatable into certain languages. To help with this, `GlSprintf`\ninterprets placeholders suffixed with `Start` and `End` to indicate the\nboundaries of a component to display within the message. Any text between\nthem is passed, via the `content` scoped slot property, to the slot name common\nto the placeholders.\n\nFor example, using `linkStart` and `linkEnd` placeholders in a message defines\na `link` scoped slot:\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\nNote that _any_ arbitrary HTML tags or Vue component(s) can be used within\na scoped slot, and that the content passed to it can be used in any way at all;\nfor instance, as 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 <p>\n {{ content }}\n <div>{{ content }}</div>\n </p>\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### Customizing start/end placeholders\n\nYou can customize the start and end placeholders that `GlSprintf` looks for\nusing the `placeholders` prop. For instance:\n\n```html\n<div>\n <gl-sprintf\n :message=\"__('Learn more about %{my_custom_start}zones%{my_custom_end}')\"\n :placeholders=\"{ link: ['my_custom_start', 'my_custom_end'] }\"\n >\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\nThis can be useful if you are migrating an existing string to `GlSprintf` that\nuses different placeholder naming conventions, and don't want invalidate\nexisting translations.\n\n## Displaying components within a message\n\nUse slots to replace placeholders in the message with the slots' contents.\nThere is a slot for every placeholder in the message. For example, the `author`\nslot name can be used when there is an `%{author}` placeholder in the message:\n\n```html\n<script>\nexport default {\n data() {\n return {\n authorName: 'Some author',\n };\n },\n};\n</script>\n\n<template>\n <div>\n <gl-sprintf :message=\"__('Written by %{author}')\">\n <template #author>\n <span>{{ authorName }}</span>\n </template>\n </gl-sprintf>\n </div>\n</template>\n```\n\nThe example above renders to this HTML:\n\n```html\n<div>Written by <span>Some author</span></div>\n```\n\n## Usage caveats\n\n### White space\n\n`GlSprintf` does not handle white space in scoped slots specially; it is passed\nthrough and rendered just like regular text. This means that white space in the\nscoped slot templates *themselves*, including newlines and indentation, are\npassed through untouched (assuming the template compiler you're using doesn't\ntrim text nodes at compile time; `vue-template-compiler` preserves white space\nby default, for instance).\n\nMost of the time you don't need to worry about this, since\n[browsers normalize white space][1] automatically, but here's an example, using\npunctuation, where you might want to be conscious of the white space in the\ntemplate:\n\n```html\n<div>\n <gl-sprintf :message=\"__('Foo %{boldStart}bar%{boldEnd}!')\">\n <template #bold=\"{ content }\">\n <b>\n {{ content }}\n </b>\n </template>\n </gl-sprintf>\n</div>\n```\n\nAs written, the literal markup rendered would be:\n\n```html\n<div> Foo <b>\n bar\n </b>!\n</div>\n```\n\nwhere the white space (including newlines) before and after `bar` is exactly\nthe newlines and indentation in the source template. The browser will render\nthis as:\n\n<div> Foo <b>\n bar\n </b>!\n</div>\n\nNote the single space between `bar` and `!`. To avoid that, remove the\nwhite space in the template, or use `v-text`:\n\n```html\n<div>\n <gl-sprintf :message=\"__('Foo %{boldStart}bar%{boldEnd}!')\">\n <template #bold=\"{ content }\">\n <b>{{ content }}</b>\n <!-- OR -->\n <b v-text=\"content\" />\n </template>\n </gl-sprintf>\n</div>\n```\n\n### Miscellaneous\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 placeholder _isn't_ provided, the placeholder\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 placeholder in the message for a provided named slot, the\n 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, i.e., it is assumed\n there is no text to extract and pass to the scoped slot. This allows you to\n use plain slots whose names end in `Start` or `End`, e.g., `backEnd`, or\n `fromStart` in isolation, without their `Start`/`End` counterparts.\n- Text extraction 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- For more examples and edge cases, please see the test suite for `GlSprintf`.\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()`] and [`String.prototype.endsWith()`] under the\nhood. Make sure those methods are polyfilled if you plan on using the component on IE11.\n\n[1]: https://www.w3.org/TR/css-text-3/#white-space-phase-1\n[`String.prototype.startsWith()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith\n[`String.prototype.endsWith()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith\n"; var sprintf_documentation = { description, followsDesignSystem: false }; export default sprintf_documentation;